Camping'meta_def'做什么?

时间:2013-09-14 02:59:12

标签: ruby camping

在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)做了什么。有人可以解释这是如何工作的吗?

1 个答案:

答案 0 :(得分: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)做了什么。

您的代码正在创建'a'方法的接收者singleton_class。{现在看看如下:

meta_def
  

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

如上所述,它首先为接收器创建一个单例类。然后使用define_method,为接收器创建一个名为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" 的方法,其主体只包含一行:meth单身课。