On Wednesday, June 15, 2011 01:05:39 PM Michael Edgar wrote:
> On Jun 15, 2011, at 1:50 PM, Ilias Lazaridis wrote:
> > Is this a defect or is there an explanation for this behaviour?
> 
> I can speak to local variables; class variables still break my brain a
> little.

I tend to think class variables are a defect in the first place. If you need 
one for some reason, it's usually much better to define it as an instance 
variable on the class, rather than as a class variable. That is, instead of:

class Foo
  @@bar = true

  def hello
    if @@bar
      puts 'Hello, world!'
    else
      puts 'Goodbye, world!'
    end
  end

  def depressed!
    @@bar = false
  end
end


Do something like this instead:


class Foo
  self << class
    attr_accessor :bar
  end

  self.bar = true

  def hello
    if self.class.bar
      puts 'Hello, world!'
    else
      puts 'Goodbye, world!'
    end
  end

  def depressed!
    self.class.bar = false
  end
end


Of course, that's a terrible example of why you'd ever want to do such a thing 
-- there's rarely a reason to have anything approaching class variables -- but 
if you need them, I think it makes much more sense to do them that way. This 
also keeps them somewhat saner across inheritance, in my opinion. That's the 
part that breaks your brain, right? This way, while subclasses seem to inherit 
class methods from the superclass, they won't automatically access the same 
values, though it's trivial to override them to do that:

class Other < Foo
  self << class
    def bar
      superclass.bar
    end
    def bar= value
      superclass.bar = value
    end
  end
end

I'd probably use the superclass value as a default until someone overrides it 
on this class, so more like:

class Other < Foo
  self << class
    def bar
      @bar || superclass.bar
    end
  end
end


It's still not as clean as I'd like it to be, but at least this generally 
obeys basic concepts I've learned elsewhere which I actually understand. I 
have never actually understood class variables.