Why doesn't Object.instance_methods(false) return expected methods in Ruby?
执行
1 | [:__binding__, :pry, :to_yaml] |
我希望它返回我之前获得的所有方法,减去BasicObject方法。我想念什么?
大多数方法不是在对象本身上定义的,而是在内核(包含在对象中的模块)上定义的。您可以看到以下内容:
Object.instance_methods(true).map(&method(:method)).map(&:owner) => [Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, #>, Kernel, Kernel, Kernel, #>, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, Kernel, BasicObject, BasicObject, BasicObject, BasicObject, BasicObject, BasicObject, BasicObject, BasicObject]
如果我打开一个新的irb窗口并运行
1 | Object.instance_methods(true).select { |sym| method(sym).owner == Object } |
我没有结果。但是,如果我要求"撬",那么我只会得到
这是因为这些实例方法来自其他祖先。下面的第7行说明了Object(在我的Ruby运行时中)没有自己的实例方法:
1 2 3 4 5 6 7 8 9 10 11 12 | 2.5.0 :001 > Object.ancestors => [Object, Kernel, BasicObject] 2.5.0 :002 > Object.instance_methods(true) => [:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_variable_get, :public_methods, :instance_variables, :method, :public_method, :define_singleton_method, :singleton_method, :public_send, :extend, :pp, :to_enum, :enum_for, :<=>, :===, :=~, :!~, :eql?, :respond_to?, :freeze, :inspect, :object_id, :send, :to_s, :display, :nil?, :hash, :class, :clone, :singleton_class, :itself, :dup, :taint, :yield_self, :untaint, :tainted?, :untrusted?, :untrust, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :!, :equal?, :instance_eval, :instance_exec, :==, :!=, :__id__, :__send__] 2.5.0 :003 > o = Object.instance_methods(false) => [] 2.5.0 :004 > k = Kernel.instance_methods(false) => [:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_variable_get, :public_methods, :instance_variables, :method, :public_method, :define_singleton_method, :singleton_method, :public_send, :extend, :pp, :to_enum, :enum_for, :<=>, :===, :=~, :!~, :eql?, :respond_to?, :freeze, :inspect, :object_id, :send, :to_s, :display, :nil?, :hash, :class, :clone, :singleton_class, :itself, :dup, :taint, :yield_self, :untaint, :tainted?, :untrusted?, :untrust, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods] 2.5.0 :005 > bo = BasicObject.instance_methods(false) => [:!, :equal?, :instance_eval, :instance_exec, :==, :!=, :__id__, :__send__] 2.5.0 :006 > Object.instance_methods(true) - (k + bo) => [] |