Ruby: 理解_why的cloaker方法

7
我正在尝试理解_why在 "A Block Costume" 中写的 cloaker 方法:
class HTML
  def cloaker &blk
    (class << self; self; end).class_eval do
      # ... rest of method
    end
  end
end

我意识到class << self; self; end打开了self的Eigenclass,但我从未见过有人在实例方法内执行此操作。在我们执行此操作时,self是什么?我认为self应该是调用该方法的接收器,但cloaker是从method_missing内部调用的:
def method_missing tag, text = nil, &blk
  # ...
  if blk
    cloaker(&blk).bind(self).call
  end
  # ...
end

method_missing方法内的self是什么?当我们调用时self是什么?

((class << self; self; end).class_eval)

cloaker 方法内部?

基本上,我想知道我们是打开 HTML 类的 Eignenclass,还是针对 HTML 类的特定实例进行操作?


2
不确定我是否理解了你的问题。method_missing是一个实例方法,因此 self 指的是特定的实例,而 class << self; self; end 返回该实例的特殊类。 - Stefan
请注意,官方术语为“singleton_class”。 - Marc-André Lafortune
1个回答

1

cloaker方法内部,self将是HTML的一个实例,因为您会在对象上调用它,所以您实际上是在HTML类实例上创建单例方法。例如:

class HTML
  def cloaker &blk
    (class << self; self; end).class_eval do
      def new_method
      end
    end
  end
end

obj = HTML.new
obj.cloaker
p HTML.methods.grep /new_method/  # []
p obj.singleton_methods # [:new_method]

编辑

或者像Jörg W Mittag评论的那样,只是调用"Object#define_singleton_method"的1.9之前的方式。


3
当然,从 Ruby 1.9 开始,这基本上只是 def cloaker(&blk) define_singleton_method(:new_method, &blk) end - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接