Ruby 内核模块方法用作对象 class 方法
Ruby Kernel module methods used as Object class methods
假设我想用我刚刚想到的一种方法修补 Kernel
模块:
module Kernel
def say_hello
puts "hello world"
end
end
我现在肯定能做到:
Object.new.say_hello # => hello world
但我还可以做以下我通常不应该做的事情:
Object.say_hello # => hello world
由于 Object
包含 Kernel
它采用其实例方法,因此所有 Object
实例都应响应 say_hello
。到目前为止一切顺利。
然而 Object.say_hello
似乎是一种 class 方法,只有我们做了类似的事情才合理:
class << Object
def say_hello
puts "hello world"
end
end
在 Object
的单例 class 中存储 say_hello
将允许我们将其用作 class 方法,而不是 Kernel
仅包含在Object
不允许这种行为。但确实如此。有人知道为什么吗?
谢谢
Kernel
is just included in Object
[...]
没错。
[...] which shouldn't allow this behavior.
你忽略了 classes 也是对象。
如果obj
是Object
的实例,让我们看看say_hello
方法来自哪里:
obj = Object.new
obj.method(:say_hello)
#=> #<Method: Object(Kernel)#say_hello>
果然不出所料。 obj
是 Object
的实例并且 Object
包括 Kernel
:
obj.class.include? Kernel
#=> true
obj.class.ancestors
#=> [Object, Kernel, BasicObject]
现在让我们看看如果 obj
是 class Object
:
会发生什么
obj = Object
obj.method(:say_hello)
#=> #<Method: Class(Kernel)#say_hello>
这次obj
是Class
的实例,Class
还包括Kernel
:
obj.class.include? Kernel
#=> true
obj.class.ancestors
#=> [Class, Module, Object, Kernel, BasicObject]
Ruby 的 documentation 指出 class 方法实际上只是在 class 对象上定义的实例方法:(强调)
class C
def self.my_method
# ...
end
end
However, this is simply a special case of a greater syntactical power in Ruby, the ability to add methods to any object. Classes are objects, so adding class methods is simply adding methods to the Class object.
假设我想用我刚刚想到的一种方法修补 Kernel
模块:
module Kernel
def say_hello
puts "hello world"
end
end
我现在肯定能做到:
Object.new.say_hello # => hello world
但我还可以做以下我通常不应该做的事情:
Object.say_hello # => hello world
由于 Object
包含 Kernel
它采用其实例方法,因此所有 Object
实例都应响应 say_hello
。到目前为止一切顺利。
然而 Object.say_hello
似乎是一种 class 方法,只有我们做了类似的事情才合理:
class << Object
def say_hello
puts "hello world"
end
end
在 Object
的单例 class 中存储 say_hello
将允许我们将其用作 class 方法,而不是 Kernel
仅包含在Object
不允许这种行为。但确实如此。有人知道为什么吗?
谢谢
Kernel
is just included inObject
[...]
没错。
[...] which shouldn't allow this behavior.
你忽略了 classes 也是对象。
如果obj
是Object
的实例,让我们看看say_hello
方法来自哪里:
obj = Object.new
obj.method(:say_hello)
#=> #<Method: Object(Kernel)#say_hello>
果然不出所料。 obj
是 Object
的实例并且 Object
包括 Kernel
:
obj.class.include? Kernel
#=> true
obj.class.ancestors
#=> [Object, Kernel, BasicObject]
现在让我们看看如果 obj
是 class Object
:
obj = Object
obj.method(:say_hello)
#=> #<Method: Class(Kernel)#say_hello>
这次obj
是Class
的实例,Class
还包括Kernel
:
obj.class.include? Kernel
#=> true
obj.class.ancestors
#=> [Class, Module, Object, Kernel, BasicObject]
Ruby 的 documentation 指出 class 方法实际上只是在 class 对象上定义的实例方法:(强调)
class C def self.my_method # ... end end
However, this is simply a special case of a greater syntactical power in Ruby, the ability to add methods to any object. Classes are objects, so adding class methods is simply adding methods to the Class object.