Instance_eval vs class_eval in module

class Foo
    include Module.new { class_eval "def lab; puts 'm' end" }

    def lab
      super 
      puts 'c'
    end
end

Foo.new.lab #=> m c

==================================================== ========================

class Foo
    include Module.new { instance_eval "def lab; puts 'm' end" }

    def lab
      super 
      puts 'c'
    end
end

Please note that I changed class_eval to instance_eval

Foo.new.lab rescue nil#=> no super class method lab
Foo.lab #=> undefined method lab for Foo class

Thus, it seems that even the module did not define an instance method and a class method.

Any explanation what is going on here?

This code has been tested on ruby ​​1.8.7 on mac.

+5
source share
2 answers

First, think about what you are doing include. This makes the method an instance of the module included in the instance methods for class inclusion. that is, besides the fact that your working example uses an anonymous module, it is equivalent:

module M1
  def lab
    puts 'm'
  end
end

class Foo
    include M1

    def lab
      super 
      puts 'c'
    end
end

, class_eval. . , , class_eval. , MyModule = Module.new { class_eval "def lab; puts 'm' end" }

module MyModule
  def lab
    puts 'm'
  end
end

, , .

instance_eval, ( ), MyMod2 = Module.new { instance_eval "def lab; puts 'm' end" }

module MyMod2
  def MyMod2.lab
    puts 'm'
  end
end

. , MyMod2.lab, include.


: , instance_eval vs. class_eval, Ruby . .

+9

, - . , , :

module Something
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def blah
      puts "lol"
    end
  end
end

class Test
  include Something
end 

IRB:

>> Test.blah
lol
=> nil
+3

All Articles