模块扩展和ruby中的class_eval

Mat*_*rix 2 ruby metaprogramming

我正在测试元编程,我有一个案例,我不明白:

module Bar
 def self.append_features klass
   klass.class_eval do
     def self.a
       puts 'a'
     end
   end
 end
end

class Foo
 extend Bar
end
Run Code Online (Sandbox Code Playgroud)

在哪里定义"a"方法?因为:

Foo.new.a,Foo.a和Class.a不起作用!

如果我在Foo类中使用include而不是extend,方法"a"是为Class Foo定义的(Foo.a可以工作),我想:如果"self"为include = Class,"self"为extend = Metaclass,但是没有.

可以解释方法"a"在哪里?

Aru*_*hit 7

append_features是ruby中的一个钩子方法,当你这样做时,它被调用include Bar.现在,它被添加类方法a的类Bar,然后它使现有的类方法aFoo.

让我来解释一下该方法如何a成为类的方法Bar.当你这样做时include Bar,会调用hook方法,并将其参数klass设置为Bar.现在klass.class_eval {..},在块内class_eval设置为.现在意味着.self{..}Bardef self.a;puts 'a';enddef Bar.a;puts 'a';end

module Bar
 def self.append_features klass
   klass.class_eval do
     def self.a
       puts 'a'
     end
   end
 end
end

class Foo
 include Bar
end

Foo.a # => a
Run Code Online (Sandbox Code Playgroud)

在哪里定义"a"方法?因为:Foo.new.a,Foo.a和Class.a不起作用!

这是因为你没有extend Bar调用hook方法append_features.所以类方法a尚未在类中定义Bar,正如您所期望的那样.

  • +1 有趣!:) 不知道`append_features`;以前从没想过 `extend` 和 `include` 的区别。 (2认同)