Metaprogramming in Ruby: class_eval vs. instance_eval

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • beatTheDevil
    New Member
    • Nov 2006
    • 16

    Metaprogramming in Ruby: class_eval vs. instance_eval

    I'm using Ruby 1.8.6 btw.

    For the longest time today (it seems) I've been trying to understand exactly the operating difference between class_eval and instance_eval. There are some obvious differences I'm perfectly aware of (e.g. class_eval is only on Class objects), but the reality is that some irb tinkering has left me more confused than ever. Given the following:

    Code:
    class Foo
      # could be any class
    end
    
    f = Foo.new
    
    # Try out instance eval on f's class (Foo)
    f.class.instance_eval do
      define_method :made_by_inst_eval do
        puts "This method was made by calling instance_eval"
        puts "Current 'self': #{self}"
        puts "Current class of 'self': #{self.class}"
      end
    end
    
    f.made_by_inst_eval
    Gives me this:

    Code:
    This method was made by calling instance_eval
    Current 'self': #<Foo:0x8f098>
    Current class of 'self': Foo
    If I then try doing the exact same thing with class_eval instead:

    Code:
    f.class.class_eval do
      define_method :made_with_class_eval do
        puts "This method was made by calling class_eval"
        puts "Current 'self': #{self}"
        puts "Current class of 'self': #{self.class}"
      end
    end
    
    f.made_with_class_eval
    I then get the same damn result:

    Code:
    This method was made by calling class_eval
    Current 'self': #<Foo:0x8ec88>
    Current class of 'self': Foo
    So, what's the difference between these two calls? In this particular situation? In general?

    Some clear thoughts would be ever so appreciated!
  • improvcornartist
    Recognized Expert Contributor
    • May 2007
    • 303

    #2
    There may not be much of a difference in this situation, since both times it is being called on f.class. I think the difference between the two is the receiver of where the method is defined, and thus what it applies to. This page may provide a little extra info around example 5.

    Comment

    Working...