Generic-user-small Victor Moroz 5 posts

Or why one should use class << obj if you have instance_eval? After all instance_eval is more convenient and is executed in the ‘obj’ scope (e.g. you can use instance methods), while class << obj is something odd as it is executed in the scope of the ghost class. What can be done in this scope except of defining singletons? Well, just about my favorite @@var@@var defined inside class << obj becomes common for all classes!


class << "dog" 
  @@var = 1
end

class << Fixnum
  puts @@var     # 1
end

class String
  puts @@var     # 1
end

This means there is not ghost class between singleton ghost class and Class while there is between String and Class for example. Confusing…

 
Generic-user-small Victor Moroz 5 posts

And even more confusing here


def String.scream
  puts 'wow'
end

String.instance_eval { scream } # wow
String.class_eval { scream } # wow

So when we execute instance_eval and class_eval both blocks are executed in the context of String class (self = String), but ‘def method’ does different things! Well, concept ‘current class’ is reasonable, but how far this concept goes? It means there are two contexts – ‘self’ for calling methods and accessing variables and ‘current class’ for defining methods? Where else these contexts are different?

 
Dave_8_trans_small Dave Thomas Administrator 70 posts

As to your first point: that’s one reason I think @@var is unusable in real code. I also suspect that example will no longer work in 1.9. In general, @@var should be avoided.

For the second point: the biggest place the two are different is at the top level of your program…

 
Generic-user-small Victor Moroz 5 posts

Actually @@var can be found in many gems, including ActiveSupport, ActiveRecord, haml etc. Of course usage I showed in this post is quite bizzare, but how are you going to share variable between several instances of the same class if you need to access it from instance methods? Well, through class method and class level @var, but it requires additional lines of code. And even if you do this for objects, you can’t do it for classes like it is done in ActiveRecord when all subclasses share the same variable. Maybe it is just wrong use of inheritance, don’t know.

Wow, I just realized that top level works as Object.class_eval block!

 
Dave_8_trans_small Dave Thomas Administrator 70 posts

Victor:

I know people use it. I just think they shouldn’t… :)

5 posts, 2 voices