【发布时间】:2009-05-08 00:15:08
【问题描述】:
自从我上次进行 Ruby 编程以来已经有一段时间了——查看其他人的代码,我在一个函数中看到了 @ sigil(不是一个方法——在任何类定义之外) ,我理解它的范围是实例成员。
模块是函数中隐含的self吗?
【问题讨论】:
自从我上次进行 Ruby 编程以来已经有一段时间了——查看其他人的代码,我在一个函数中看到了 @ sigil(不是一个方法——在任何类定义之外) ,我理解它的范围是实例成员。
模块是函数中隐含的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
【讨论】: