[rspec-users] class << self considered harmful... really?

Zach Dennis zach.dennis at gmail.com
Thu Nov 27 11:38:48 EST 2008


On Wed, Nov 26, 2008 at 8:46 PM, Ben Mabey <ben at benmabey.com> wrote:
> Avdi Grimm wrote:
>>
>> On Wed, Nov 26, 2008 at 12:17 PM, Matt Wynne <matt at mattwynne.net> wrote:
>>
>>>>
>>>> And class variables are problematic in Rails in development mode because
>>>> of class reloading.
>>>>
>>>
>>> And more generally dangerous for threading reasons, right?
>>>
>>
>>
>> All of the above.  My rule of thumb is: don't use them unless I have a
>> very, very good reason.  I can't think of the last time I had that
>> good a reason.
>>
>>
>
> So.. you are saying that this is preferred:
>
> class State < AR:Base
>
>  def self.names
>     @names ||= State.all.map{|s| s.name}
>  end
>
> end
>
> to this:
>
> class State < AR:Base
>
>  def self.names
>     @@names ||= State.all.map{|s| s.name}
>  end
>
> end
>
> Is that correct?
>
> How is using a class instance variable safer from a threading point of view?
>  Do threads not share class instance variables the same way class variables
> would be shared?
>

AFAIK it isn't any safer from a threading point of view.

My biggest hate of class variables is that they are shared throughout
an entire inheritance hierarchy (and I do not find @@ aesthetically
pleasing). Class instance variables are not.

class A
   def self.foo
      @@foo
   end

   def self.foo=a
       @@foo = a
   end
end

class B < A ; end
class C < B ; end

A.foo = 1
A.foo # => 1

C.foo # => 1
C.foo = 10
C.foo # => 10
A.foo # => 10 -- surprise!

Class instance variables don't have this problem.

class A
   def self.foo
      @foo
   end

   def self.foo=a
       @foo = a
   end
end

class B < A ; end
class C < B ; end

A.foo = 1
A.foo # => 1

C.foo # => nil
C.foo = 10
C.foo # => 10
A.foo # => 1


-- 
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com


More information about the rspec-users mailing list