Ilya
Ilya

Reputation: 13477

Enumerate_it gem strange code in class methods

I stumbled on strange code in enumerate_it gem:

module EnumerateIt
  module ClassMethods
    def has_enumeration_for(attribute, options = {})
      self.enumerations = self.enumerations.dup
      ...
    end
end

It seems senseless for me, but I sure gem developers had reasons to write this. What is the reason to use assignment like this?

Upvotes: 2

Views: 345

Answers (1)

Jakob S
Jakob S

Reputation: 20125

Oooh, code archeology! Luckily, this is an open source project, so we have access to the history of the code, and - hopefully - the reasons for changes (as described in commit messages).

The code in question:

self.enumerations = self.enumerations.dup

was originally added in commit 04bec59407bf14d3ab219c4b505ef1fbfce0c398, which has a pretty good commit message that explains why it was added:

Respect superclass enumerations on subclasses

Previously, this was the behavior:

class Unico::Person
  has_enumeration_for :gender
end

class Person < Unico::Person
end

Unico::Person.enumerations
# => {:gender => Gender}

Person.enumerations
# => {}

After this commit, subclasses will inherit the superclass enumerations:

class Unico::Person
  has_enumeration_for :gender
end

class Person < Unico::Person
end

Unico::Person.enumerations
# => {:gender => Gender}

Person.enumerations
# => {:gender => Gender}

How to find that

Check out a copy of the repository:

$ git clone https://github.com/cassiomarques/enumerate_it.git
Cloning into 'enumerate_it'...
remote: Counting objects: 995, done.
remote: Total 995 (delta 0), reused 0 (delta 0), pack-reused 995
Receiving objects: 100% (995/995), 178.90 KiB | 0 bytes/s, done.
Resolving deltas: 100% (474/474), done.
Checking connectivity... done.
$ cd enumerate_it

Now, let's find all commits containing the code in question:

$ git log -S "self.enumerations = self.enumerations.dup"
commit c99a15c31d156464b1139533d4377331b6e21fff
Author: Cássio Marques <[email protected]>
Date:   Thu Nov 8 17:16:36 2012 -0200

    We should extend the EnumerateIt module instead of including it, since the has_enumeration_for is a class method

commit 04bec59407bf14d3ab219c4b505ef1fbfce0c398
Author: Gabriel Sobrinho <[email protected]>
Date:   Thu May 31 11:08:57 2012 -0300

    Respect superclass enumerations on subclasses

    Previously, this was the behavior:

      class Unico::Person
        has_enumeration_for :gender
      end

      class Person < Unico::Person
      end

      Unico::Person.enumerations
      # => {:gender => Gender}

      Person.enumerations
      # => {}

    After this commit, subclasses will inherit the superclass enumerations:

      class Unico::Person
        has_enumeration_for :gender
      end

      class Person < Unico::Person
      end

      Unico::Person.enumerations
      # => {:gender => Gender}

      Person.enumerations
      # => {:gender => Gender}

Looking closer at the commits with git show reveals that the topmost one was simply moving the code from one place to another, while the latter commit actually added the code.

And that's the commit we wanted.

Upvotes: 3

Related Questions