在Ruby中,顶级分配有什么作用?

时间:2018-09-16 03:29:30

标签: ruby global-variables variable-assignment toplevel

.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))的确切作用是什么?

4 个答案:

答案 0 :(得分:2)

  

为什么这不起作用?为什么从Times内部访问f,但不能从three_times内部访问

名称以小写字母开头的变量是局部变量。本地变量在定义它们的作用域内是本地的(这就是为什么它们被称为 local 变量的原因。)

名称以大写字母开头的变量是常量。首先在默认常量范围内查找常量,然后从词汇表向外查找,然后通过继承动态向上查找。

  

更笼统地说,顶层任务(例如three_times = Times.new(3))的确切作用是什么?

没什么特别的。它所做的事情与其他地方的任务相同。在这种情况下,它是:

  1. 取消引用变量(常量)Times,我们将此对象称为 o1
  2. 计算文字整数表达式3,我们将结果对象称为 o2
  3. 将消息new发送到 o1 ,并传递 o2 作为参数。我们称之为发送 o3 的消息的答案。
  4. 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()