0

在 camping.rb 的第一行之一:https://github.com/camping/camping/blob/ae5a9fabfbd02ba2361ad8831c15d723d3740b7e/lib/camping-unabridged.rb#L17

框架将meta_def方法添加到Object类中。我一直在玩这段代码,但我仍然无法理解它在做什么。

class Object #:nodoc:
  def meta_def(m,&b) #:nodoc:
    (class<<self;self end).send(:define_method,m,&b)
  end
end

当我尝试这样打印时(class<<self;self end)

class Object #:nodoc:
  def meta_def(m,&b) #:nodoc:
    puts (class<<self;self end)
  end
end

puts 'a'.meta_def 'boo'

它打印出来#<Class:#<String:0x146810>>,这意味着它正在创建一个Class. 但是,我仍然不知道它到底是什么以及做了什么(class<<self;self end)。有人可以解释这是如何工作的吗?

4

1 回答 1

1
class Object 
  def meta_def(m,&b) 
    (class<<self;self end)
  end
end
ob = 'a'
ob.meta_def 'boo' # => #<Class:#<String:0x94daf54>>
ob.singleton_class # => #<Class:#<String:0x94daf54>

我仍然不知道它到底是什么以及做了什么(class<<self;self end)

您的代码正在创建singleton_class方法的接收器('a'meta_def。现在看下面:

class Object #:nodoc:
  def meta_def(m,&b) #:nodoc:
    (class<<self;self end).send(:define_method,m,&b)
  end
end
ob = 'foo'
ob.meta_def(:meth) {"Welcome"}
ob.meth # => "Welcome"

现在在上面的代码中,该行在做什么?

如上所述,它首先为接收者创建一个单例类。然后使用,为接收者单例类创建一个以仅包含一行的主体define_method命名的方法。:meth"Hello"

于 2013-09-14T04:21:57.470 回答