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