顶级方法中“ self”的规则是什么?

时间:2018-07-27 21:44:20

标签: ruby self

如果我在Ruby文件中定义一个顶级方法,则self的值似乎在很大程度上取决于谁在调用它。

def who_am_i
  puts self.inspect
end

class A
  def self.foo
    who_am_i
  end
  def foo
    who_am_i
  end
end

def foo
  who_am_i
end

foo       # >> main
A.foo     # >> A
A.new.foo # >> #<A:...>

很显然,如果在类中中定义了方法,则self可以是类本身(对于类方法)或类的相关实例(对于实例方法)。根据上面显示的试验,似乎在类中定义的方法 not 从其调用方继承了self,但是我找不到任何官方参考或任何支持该参考的内容。有人可以提供描述这种行为的官方资料,理想情况下是为什么这种方式起作用的原理吗?

3 个答案:

答案 0 :(得分:1)

每当Ruby启动时Ruby都会创建一个名为main的对象,并且main是Ruby程序的顶级上下文(又称顶级范围)。在顶级范围内定义的方法(即未包装在类或模块中的方法)将绑定到主对象。

更多参考herehere

答案 1 :(得分:1)

是的,正如绝地武士所提到的,在红宝石中,您总是处在某种物体的上下文中。红宝石中没有函数,只有方法。 方法是在某个对象上定义的(确切地说是在其类或单例类上)。

您可以想到main,就像您以这种方式运行程序一样:

main_obj = Object.new
main_obj.instance_eval do
  # your program goes here

  # this defines method on `main_obj` singleton class
  def f
    puts 123
  end

  f
end

我想您可以阅读this question

答案 2 :(得分:1)

main对象的上下文中定义的所有方法,将成为Object上的[private]方法。由于一切都是对象,因此该方法将随处可用。这也是self根据您调用它的位置进行更改的原因:这些都是不同的对象,但是它们也都继承了此方法。

private_methods.include?(:who_am_i) # => true
foo       # => "main"
A.private_methods.include?(:who_am_i) # => true
A.foo    # => "A"
A.new.private_methods.include?(:who_am_i) # => true
A.new.foo # => "#<A:0x00007feaad034e00>"