自从我上次进行 Ruby 编程以来已经有一段时间了——查看别人的代码,我在一个函数(不是@
方法——任何类定义的外部)中看到了印记,我理解它的范围仅限于实例成员。
模块是隐含self
在功能中的吗?
在顶级函数(实际上仍然是一个方法)中,您处于一个稍微奇怪的地方:全局“主”空间(请参阅运行时的提示irb
,或尝试查看self
此类函数内部),还有这些函数被定义为Object
类内部的私有方法。
$ cat foo
def foo
p self
p self.class
puts 'foo'
end
foo
Object.foo
$ ruby foo
main
Object
foo
foo:8: private method `foo' called for Object:Class (NoMethodError)
$
你可以通过显式声明这些方法来绕过这个public
,但我不确定我是否喜欢这个!奇怪的是,如果您在 内部定义了一个顶级方法irb
,那么您可以通过类方法调用它,Object#foo
而无需将其声明为 public。
所以这是一种“隐含的主命名空间被入侵Object
(但嘘不要告诉任何人)”。@foo
在顶级函数中定义的对象在 Object 中可用,作为普通的旧属性。有点。如果您的顶级方法集@foo
并且您在没有作用域的情况下调用它,则它在类似特征的main
命名空间中声明,但如果您通过调用类方法,Object
则@foo
出现在Object
.
另一个例子:
public
def set_foo
@foo = 'foo'
end
def get_foo
@foo
end
def Object.get_foo_again
@foo
end
set_foo
p get_foo
p Object.get_foo_again
Object.set_foo
p Object.get_foo_again
给
"foo" # @foo set in main
nil # @foo nil in Object
"foo" # @foo in Object
反之亦然。
认为这是“一个函数,而不是一个方法”的假设是错误的。所有 Ruby 代码都出现在某个对象的上下文中。“全局”上下文是一个名为的对象(如果您不相信,请main
尝试)。ruby -e "puts self"
在顶层范围内定义的方法成为 Object 的实例方法。这意味着该方法将在任何地方可用,self
具体取决于调用方法的位置(以及实例变量所属的上下文)
我认为它的范围是一个模块。
@ 使变量成为实例变量。听起来它不是显式声明的类的一部分,因此正如 Chuck 指出的那样,它将在主对象中可用。通过示例更容易说明:
$ irb
irb(main):001:0> @var = 1
=> 1
irb(main):002:0> class New
irb(main):003:1> def test
irb(main):004:2> puts @var
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> test = New.new
=> #<New:0xb7ccbc14>
irb(main):008:0> test.test
nil
=> nil
irb(main):009:0> def test2
irb(main):010:1> puts @var
irb(main):011:1> end
=> nil
irb(main):012:0> test2
1
=> nil