Why doesn't Object.instance_methods(false) return expected methods in Ruby?

时间:2018-02-03 07:36:25

标签: ruby

When I execute Object.instance_methods(true), I get all the instance methods listed on http://ruby-doc.org/core-2.5.0/Object.html (plus most of the instance methods defined in BasicObject; I'm not really sure why I don't get all of BasicObject's instance methods, but that's another question). However, when I execute Object.instance_methods(false), I only get

[:__binding__, :pry, :to_yaml]

I expected it to return all the methods I got before, minus the BasicObject methods. What am I missing?

2 个答案:

答案 0 :(得分:4)

Most of the methods are not defined on Object itself, they are defined on Kernel (a module that gets included to Object). You can see this:

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]

If I open a new irb window and run

Object.instance_methods(true).select { |sym| method(sym).owner == Object }

I get no results. But if I require 'pry', then I get only [:pry, :__binding__]

答案 1 :(得分:2)

This is because those instance methods are coming from other ancestors. Line #7 below illustrates that Object (in my Ruby runtime) has no instance methods of its own:

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)
 => []
相关问题