2014-04-22 24 views
0

我无法弄清楚这是谁主要在C工作的人。范围在Ruby中如何工作?

以下代码是如何合理的?

if true 
    hi = "hello" 
end 

puts hi 

我已经习惯了hiputs的范围不是,所以它会报错。 Ruby中的作用域如何工作。我似乎无法找到一个清楚的教程解释它。

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

回答

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

在Ruby中,我们有4个领域 -

  1. 顶层范围
  2. def创建一个新的范围
  3. class创建一个新的范围
  4. module创建一个新的范围。

在你的情况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' 

作为defbaz内创建一个完全崭新的范围,从而,该范围不知道关于foo和它的对象。同样的,在baz里面,我创建了一个新的变量bar,但是它不知道baz的范围,因此顶层也是反对bar的对象。

+0

块创建一个新的范围,以及 – freedrull

+0

所以是最高级别范围可全部通过'def'?如果我在任何地方创建一个变量,即使在深度嵌套的if循环树中,它也可以在其外部使用吗? – user212541

+0

@ user212541没有'def'创建一个新的范围,这是一个全新的,与顶层不同的范围。对于你的第二个问题,是的。 –