为什么在Object.private_methods中提到了在顶层创建的方法?

时间:2014-06-28 19:47:15

标签: ruby self

据我所知,在Ruby的顶层创建的方法成为Object的私有实例方法。但是为什么在调用zzz时在数组中返回Object.private_methods方法名称?为什么Objectself会返回不同的私有实例方法名称?

def zzz
   puts 'zzz'
end

p Object.private_instace_methods(false) #[:zzz]
p self.private_methods(false) # [:public, :private, :include, :using, :define_method, :zzz]

p Object.private_methods() #[:inherited, :initialize, :included,..., :zzz,..., :String, :Array, :singleton_method_undefined, :method_missing]
p Object.private_methods(false) #[:inherited, :initialize]

class Temp
  private
  def hello()
    'Hello'
  end
end

p Temp.private_instance_methods(false) # [:hello]
p Temp.new.private_methods(false) # [:hello]

p Temp.private_methods() # [:inherited, :initialize, :included, :extended,...., :zzz,..., :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :method_missing]  
#`zzz` is in list, but there is no `:hello`

p Temp.private_methods(false) # [:inherited, :initialize]

2 个答案:

答案 0 :(得分:1)

  

但是为什么在调用Object.private_methods时会在数组中返回zzz方法名?

toplevel中的self是一个名为'main'的对象,'main'是一个Object类的实例:

p self
p self.class

--output:--
main
Object

班级的private_instance_methods(),例如对象,是类的实例的private_methods(),例如'主'。

  

为什么Object和self会返回不同的实例方法名称?

那不可能是因为self / main不是Class,因此self / main不响应instance_methods():

p self.instance_methods

--output:--
1.rb:3:in `<main>': undefined method `instance_methods' for main:Object (NoMethodError)

至于此:

p Object.private_methods(false)

--output:--
[:inherited, :initialize]

对象与所有类一样,是Class的实例,因此Class的private_instance_methods()

p Class.private_instance_methods(false)

--output:--
[:inherited, :initialize]

是Class实例的private_methods(),例如对象:

p Object.private_methods(false)

--output:--
[:inherited, :initialize]

而且:

Temp.private_methods() # [:inherited, :initialize, :included, :extended,...., :zzz,..., :singleton_method_added, :singleton_method_removed, :singleton_method_undefined, :method_missing]  
#`zzz` is in list, but there is no `:hello`

zzz()是Object中定义的方法,这意味着ALL个对象继承该方法。 Temp是一个类,但Temp也是一个对象(它是Class的一个实例):

puts Temp.class

--output:--
Class

因此Temp对象从Object继承方法zzz()。实际上,所有对象都可以调用zzz(),因为所有对象都继承自Object,但由于zzz是Object中的私有实例方法,因此无法指定接收者:

def zzz
  puts 'zzz'
end

class Temp
  puts self  #=>Temp
  zzz        #When you don't specify a receiver for a method call
             #ruby uses self, so that line is equivalent to
             #self.zzz, which is equivalent to Temp.zzz

  def hello
    puts 'Hello!'

    puts self  #=>Temp_instance
    zzz        #Same as self.zz, which is equivalent to Temp_instance.zz 
  end
end

--output:--
Temp
zzz
Hello!
#<Temp:0x00000101136238>  
zzz

方法hello()只能由Temp类的实例调用,所以Temp可以调用zzz(),但Temp不能调用hello():

class Temp
  def hello
    puts 'Hello!'
  end
end

Temp.new.hello 
Temp.hello

--output:--
Hello!
1.rb:8:in `<main>': undefined method `hello' for Temp:Class (NoMethodError)

答案 1 :(得分:0)

类是对象。 Object是一个Class,因此它获取Object的实例方法,就像其他所有对象一样。