我在.rb
文件的顶层有以下代码:
class Times
def initialize(n)
@n = n
end
def each()
(1..@n).each {yield}
end
end
three_times = Times.new(3)
def f()
Times.new(3).each {puts 'Test'}
end
f()
这可以工作,并按预期打印“测试”三次。但是,如果我用Times.new(3)
替换f
中的three_times
,即three_times.each {puts 'Test'}
,我收到一个错误:
`f': undefined local variable or method `three_times' for main:Object (NameError)
为什么这不起作用?为什么Times
可以从f
内部访问,但不能访问three_times
?
更一般地说,顶层的任务究竟是什么(例如three_times = Times.new(3)
)呢?
为什么这不起作用?为什么
Times
可以从f
内部访问,但不能访问three_times
?
名称以小写字母开头的变量是局部变量。局部变量是它们定义的范围的局部变量(这就是它们被称为局部变量的原因。)
名称以大写字母开头的变量是常量。常量首先在默认的常量范围中查找,然后在词法上向外查找,然后通过继承动态向上查找。
更一般地说,顶层的任务究竟是什么(例如
three_times = Times.new(3)
)呢?
没什么特别的。它在其他任何地方做的任务都是一样的。在这种情况下,它:
Times
,让我们称这个对象为o1。3
,让我们调用结果对象o2。new
发送到o1,将o2作为参数传递。让我们来回复一下该消息发送o3。three_times
的局部变量。正如您所看到的,那里没有任何特定于脚本范围或顶级的特定内容。
这是因为它正在寻找一个名为“three_times”的局部变量。如果您希望将“three_times”设置为“top-level”或“global”,请在变量名前加上$,使其为“$ three_times”。
因为
three_times
是一个局部变量def
创造了一个新的范围因此,当调用f时,它看不到或无法访问three_times
要访问three_times,请将其更改为全局变量$three_times
或实例变量@three_times
你能够引用类Times的原因是它是一个常量,ruby经历了一个单独的常量查找过程。
与def
的散步问题
您还可以使用块来定义方法来访问局部变量,该方法可以避开整个范围门问题。我有时在编写rake任务时这样做但很少在脚本之外执行。
three_times = Times.new(3)
define_method :foo do
three_times.each { puts 'Tests'}
end
foo
您的代码适合我,没有错误。你可以sucecsfully打电话给f()