范围如何在Ruby中运行?

时间:2014-04-22 02:19:21

标签: ruby-on-rails ruby

我不能把这想象成一个主要在C工作的人。

以下代码如何合理?

if true
    hi = "hello"
end

puts hi

我习惯hi不在puts范围内,所以会出错。 Ruby中的作用域如何工作。我似乎无法找到解释它的明确教程。

即使这是有效的,这是好的做法吗?

2 个答案:

答案 0 :(得分:6)

在Ruby中,有5个范围:

  • 脚本范围
  • 模块范围
  • 班级范围
  • 方法范围
  • 阻止范围

阻止范围嵌套,其他的不包括在内。块可以关闭他们的词汇环境,其他人不能。 (IOW:他们不仅在他们的词汇周围环境中筑巢,即可以从他们的词汇周围环境中获取变量,他们甚至可以在周围环境不再存在之后继续这样做。)

与其他语言不同,Ruby没有局部变量的顶级或全局范围。 "最大"范围是脚本范围,但不是全局的,它仅限于单个脚本。 (通常,脚本与文件相同,但有些Ruby实现不使用文件,因此像"文件范围"这样的术语会产生误导。)

局部变量是从定义解析的位置定义的,并从定义执行的点开始初始化。在两者之间,当它们被定义但未初始化时,它们会评估为nil

考虑这个稍微修改过的例子:

if false
  hi = 'hello'
end

hi
# => nil
# hi is defined here, because its definition was parsed

if true
  hi = 'olleh'
end

hi
# => 'olleh'
# hi is initialized here, because its definition was executed

答案 1 :(得分:1)

在Ruby中我们有4个范围 -

  1. 顶级范围
  2. def创建新范围
  3. class创建新范围
  4. module创建了一个新范围。
  5. 在您的情况下,hi是一个在顶级范围中创建的局部变量。正如我上面所说if没有创建新范围,因此它使用默认范围,即顶级范围,并在hi >顶级范围。

    示例:

    foo = 12
    
    def baz
      p foo # undefined local variable or method `foo' 
      bar = 2 
    end
    
    bar # undefined local variable or method `bar'
    

    由于def创建了一个完全全新的范围,因此在baz内,该范围不知道foo并且它是对象。同样,在baz内部,我创建了一个新变量bar,但是baz范围的外部并不知道,因此顶层也反对bar。 }。