如果想知道實例上有哪些方法可以使用,可以有幾個方法:
- methods:取得實例上非private方法
- public_methods:取得實例上public方法
- protected_methods:取得實例上protected方法
- private_methods:取得實例上private方法
取得的清單預設包括類別上定義的實例方法與物件本身的單例方法,呼叫如果給定一個false,表示僅取得物件本身的方法,也就是單例方法。例如:
>> o = Object.new
=> #<Object:0x25e0018>
>> o.methods
=> [:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone,
:dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust
, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_
methods, :protected_methods, :private_methods, :public_methods, :instance_variab
les, :instance_variable_get, :instance_variable_set, :instance_variable_defined?
, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :re
spond_to_missing?, :extend, :display, :method, :public_method, :define_singleton
_method, :__id__, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :insta
nce_eval, :instance_exec, :__send__]
>> o.methods(false)
=> []
>> def o.some; end
=> nil
>> o.methods(false)
=> [:some]
>>
=> #<Object:0x25e0018>
>> o.methods
=> [:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone,
:dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust
, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_
methods, :protected_methods, :private_methods, :public_methods, :instance_variab
les, :instance_variable_get, :instance_variable_set, :instance_variable_defined?
, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :re
spond_to_missing?, :extend, :display, :method, :public_method, :define_singleton
_method, :__id__, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :insta
nce_eval, :instance_exec, :__send__]
>> o.methods(false)
=> []
>> def o.some; end
=> nil
>> o.methods(false)
=> [:some]
>>
Object繼承自BasicObject,並含括了Kernel模組的private實例方法(也就是那些頂層方法),沒有自已定義private或protected實例方法,因此:
>> o.private_methods.size
=> 69
>> o.protected_methods.size
=> 0
>>
=> 69
>> o.protected_methods.size
=> 0
>>
如果想得知物件上的單例方法,可以使用singleton_methods方法:
>> o.singleton_methods
=> [:some]
>>
=> [:some]
>>
想要快速得知物件上是不是有某些方法,可以在取得清單之後使用include?,或者是使用grep配合規則表示式(Regular expression)。例如:
>> "".methods.include? :upcase
=> true
>> "".methods.grep(/case/)
=> [:casecmp, :upcase, :downcase, :swapcase, :upcase!, :downcase!, :swapcase!]
>> "".methods.grep(/.!/)
=> [:succ!, :next!, :upcase!, :downcase!, :capitalize!, :swapcase!, :reverse!, :
sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr!, :tr_s!, :delet
e!, :squeeze!, :slice!, :encode!]
>> "".methods.grep(/.\\?/)
=> [:eql?, :empty?, :include?, :start_with?, :end_with?, :valid_encoding?, :asci
i_only?, :between?, :nil?, :tainted?, :untrusted?, :frozen?, :instance_variable_
defined?, :instance_of?, :kind_of?, :is_a?, :respond_to?, :respond_to_missing?,
:equal?]
>>
=> true
>> "".methods.grep(/case/)
=> [:casecmp, :upcase, :downcase, :swapcase, :upcase!, :downcase!, :swapcase!]
>> "".methods.grep(/.!/)
=> [:succ!, :next!, :upcase!, :downcase!, :capitalize!, :swapcase!, :reverse!, :
sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr!, :tr_s!, :delet
e!, :squeeze!, :slice!, :encode!]
>> "".methods.grep(/.\\?/)
=> [:eql?, :empty?, :include?, :start_with?, :end_with?, :valid_encoding?, :asci
i_only?, :between?, :nil?, :tainted?, :untrusted?, :frozen?, :instance_variable_
defined?, :instance_of?, :kind_of?, :is_a?, :respond_to?, :respond_to_missing?,
:equal?]
>>
如果使用respond_to?查詢物件是否對某訊息回應,只有public方法才會傳回true,protected或private方法會傳回false。
對於類別或模組本身定義的實例方法,可以使用以下幾個方法取得清單:
- instance_methods:可取得類別或模組上定義的非private實例方法
- public_instance_methods:可取得類別或模組上定義的public實例方法
- protected_instance_methods:可取得類別或模組上定義的protected實例方法
- private_instance_methods:可取得類別或模組上定義的private實例方法
同樣地,如果呼叫方法時加上false,表示僅取得類別或模組中定義的實例方法,排除繼承或含括而來的實例方法。例如:
>> Object.instance_methods
=> [:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone,
:dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust
, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_
methods, :protected_methods, :private_methods, :public_methods, :instance_variab
les, :instance_variable_get, :instance_variable_set, :instance_variable_defined?
, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :re
spond_to_missing?, :extend, :display, :method, :public_method, :define_singleton
_method, :__id__, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :insta
nce_eval, :instance_exec, :__send__]
>> Object.instance_methods(false)
=> []
>>
=> [:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone,
:dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust
, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_
methods, :protected_methods, :private_methods, :public_methods, :instance_variab
les, :instance_variable_get, :instance_variable_set, :instance_variable_defined?
, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :re
spond_to_missing?, :extend, :display, :method, :public_method, :define_singleton
_method, :__id__, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :insta
nce_eval, :instance_exec, :__send__]
>> Object.instance_methods(false)
=> []
>>
想得知類別或模組本身定義的類別或模組方法,可以使用以下兩個方法取得清單:
- public_class_method:取得public的模組或類別方法
- private_class_method:取得private的模組或類別方法
如果想取得實例化物件的類別,可以使用class方法,如果想知道類別的父類別,可以使用superclass方法,如果想取得物件的單例類別,可以使用singleton_class。
如果想知道目前的 區域或全域變數清單,可以使用local_variables與global_variables方法,如果想知道物件的實例變數,可以使用 instance_variables方法,如果想知道類別或模組變數,可以使用class_variables方法。例如:
>> class Some
>> @@x = 10
>> def initialize(value)
>> @value = value
>> end
>> end
=> nil
>> s = Some.new(1)
=> #<Some:0x279e8e0 @value=1>
>> local_variables
=> [:s, :_]
>> global_variables
=> [:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE, :$-K, :$
,, :$/, :$-0, :$\\, :$_, :$stdin, :$stdout, :$stderr, :$>, :$<, :$., :$FILENAME,
:$-i, :$*, :$?, :$$, :$:, :$-I, :$LOAD_PATH, :$", :$LOADED_FEATURES, :$VERBOSE,
:$-v, :$-w, :$-W, :$DEBUG, :$-d, :$0, :$PROGRAM_NAME, :$-p, :$-l, :$-a, :$bindin
g, :$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9]
>> s.instance_variables
=> [:@value]
>> Some.class_variables
=> [:@@x]
>>
>> @@x = 10
>> def initialize(value)
>> @value = value
>> end
>> end
=> nil
>> s = Some.new(1)
=> #<Some:0x279e8e0 @value=1>
>> local_variables
=> [:s, :_]
>> global_variables
=> [:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE, :$-K, :$
,, :$/, :$-0, :$\\, :$_, :$stdin, :$stdout, :$stderr, :$>, :$<, :$., :$FILENAME,
:$-i, :$*, :$?, :$$, :$:, :$-I, :$LOAD_PATH, :$", :$LOADED_FEATURES, :$VERBOSE,
:$-v, :$-w, :$-W, :$DEBUG, :$-d, :$0, :$PROGRAM_NAME, :$-p, :$-l, :$-a, :$bindin
g, :$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9]
>> s.instance_variables
=> [:@value]
>> Some.class_variables
=> [:@@x]
>>
想得知變數是哪個範圍的變數,可以使用defined?方法:
>> x = 10
=> 10
>> X = 10
=> 10
>> defined? x
=> "local-variable"
>> defined? X
=> "constant"
>> defined? xyz
=> nil
>>
=> 10
>> X = 10
=> 10
>> defined? x
=> "local-variable"
>> defined? X
=> "constant"
>> defined? xyz
=> nil
>>
如果想取得某個類別的所有實例,可以透過ObjectSpace。例如:
>> class Some
>> attr_accessor :value
>> def initialize(value)
>> @value = value
>> end
>> end
=> nil
>> s1 = Some.new(10)
=> #<Some:0x22b2a00 @value=10>
>> s2 = Some.new(20)
=> #<Some:0x266a3f0 @value=20>
>> ObjectSpace.each_object(Some) { |s| puts s }
#<Some:0x22b2a00>
#<Some:0x266a3f0>
=> 2
>>
>> attr_accessor :value
>> def initialize(value)
>> @value = value
>> end
>> end
=> nil
>> s1 = Some.new(10)
=> #<Some:0x22b2a00 @value=10>
>> s2 = Some.new(20)
=> #<Some:0x266a3f0 @value=20>
>> ObjectSpace.each_object(Some) { |s| puts s }
#<Some:0x22b2a00>
#<Some:0x266a3f0>
=> 2
>>