顶级方法中“self”的规则是什么?
What are the rules for `self` in a top-level method?
如果我在 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:...>
显然,如果一个方法定义在中一个class,self
要么是class本身(对于class 方法)或 class 的相关实例(例如方法)。根据上面的试验,似乎 not 中定义的方法 class 从其调用者继承 self
,但我找不到任何官方参考或任何支持它的东西。有人可以提供描述这种行为的官方来源,最好是它为什么这样工作的理由吗?
Ruby 在 Ruby 启动时创建一个名为 main 的对象,main 是 Ruby 程序的顶级上下文(也称为顶级范围)。在顶级范围内定义的方法(即未包装在 class 或模块中的方法)将绑定到主对象。
是的,正如绝地武士提到的,在 ruby 中你总是处于某个对象的上下文中。 ruby 中没有函数之类的东西,只有方法。
方法是在某个对象上定义的(准确地说是在其 class 或单例 class 上)。
您可以像 运行 那样想 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
在 main
对象的上下文中定义的所有方法都将成为 Object
上的 [私有] 方法。因为一切都是对象,所以这个方法随处可用。这也是为什么 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>"
如果我在 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:...>
显然,如果一个方法定义在中一个class,self
要么是class本身(对于class 方法)或 class 的相关实例(例如方法)。根据上面的试验,似乎 not 中定义的方法 class 从其调用者继承 self
,但我找不到任何官方参考或任何支持它的东西。有人可以提供描述这种行为的官方来源,最好是它为什么这样工作的理由吗?
Ruby 在 Ruby 启动时创建一个名为 main 的对象,main 是 Ruby 程序的顶级上下文(也称为顶级范围)。在顶级范围内定义的方法(即未包装在 class 或模块中的方法)将绑定到主对象。
是的,正如绝地武士提到的,在 ruby 中你总是处于某个对象的上下文中。 ruby 中没有函数之类的东西,只有方法。 方法是在某个对象上定义的(准确地说是在其 class 或单例 class 上)。
您可以像 运行 那样想 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
在 main
对象的上下文中定义的所有方法都将成为 Object
上的 [私有] 方法。因为一切都是对象,所以这个方法随处可用。这也是为什么 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>"