在.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)
)的确切作用是什么?
答案 0 :(得分:2)
为什么这不起作用?为什么从
?Times
内部访问f
,但不能从three_times
内部访问
名称以小写字母开头的变量是局部变量。本地变量在定义它们的作用域内是本地的(这就是为什么它们被称为 local 变量的原因。)
名称以大写字母开头的变量是常量。首先在默认常量范围内查找常量,然后从词汇表向外查找,然后通过继承动态向上查找。
更笼统地说,顶层任务(例如
three_times = Times.new(3)
)的确切作用是什么?
没什么特别的。它所做的事情与其他地方的任务相同。在这种情况下,它是:
Times
,我们将此对象称为 o1 。3
,我们将结果对象称为 o2 。new
发送到 o1 ,并传递 o2 作为参数。我们称之为发送 o3 的消息的答案。three_times
的局部变量。如您所见,其中没有什么是脚本作用域或顶层特有的。
答案 1 :(得分:1)
这是因为它正在寻找一个名为“ three_times”的局部变量。如果希望将“ three_times”设置为“ top-level”或“ global”,请在变量名前加上$,使其为“ $ three_times”。
答案 2 :(得分:1)
因为
three_times
是局部变量def
创建了一个新范围因此,在调用f时,它看不到或无法访问three_times
要访问三次,请将其更改为全局变量$three_times
或实例变量@three_times
之所以能够引用Times类,是因为它是一个常量,而ruby会通过单独的常量查找过程进行操作。
def
的分步问题
您还可以通过使用块来定义您的方法来访问局部变量,从而避免了整个范围门问题。我有时在编写瑞克任务时这样做,但是很少在脚本之外执行。
three_times = Times.new(3)
define_method :foo do
three_times.each { puts 'Tests'}
end
foo
答案 3 :(得分:0)
您的代码对我有用,没有错误。您可以成功致电f()