Dir.foreach()Ruby中的本地范围

时间:2017-01-14 02:56:10

标签: ruby scope global-variables

为什么Dir.foreach循环中变量的范围是本地的?

我正在循环浏览文件,直到我从文件中找到我需要的信息并将其设置为等于变量,但在循环之外,变量无法被看到。我现在使用的是全局变量,但由于Ruby不受欢迎,我不想这样做。

3 个答案:

答案 0 :(得分:2)

当您在块中设置变量时,除非在外部范围中有先前定义的变量,否则它将无法从外部范围获得。

"全球"只是意味着最外层的范围。范围有两个主要级别 - 方法和块。在任何一种情况下,您都会看到相同的行为。

a = 0
def foo
  a = 1
  b = 2
end
foo
a # => 1
b # => NameError

1.times do
  a = 2
  b = 3  
end
a # => 2
b # => NameError

答案 1 :(得分:0)

如果您只需要一个元素,请使用find

fname = Dir.foreach('.').find { |each| each =~ /store/i }

否则Maxple说,当你在一个块中定义一个变量时,它只在那个块的范围内定义,而不是在外部。如果要在内部和外部使用变量,则必须在块之前定义变量。

但如上所述,您几乎总是可以在Enumerable模块上使用函数。有用的是selectfind以及mapany?,最好阅读文档。

答案 2 :(得分:0)

局部变量是它们定义的范围的局部变量。毕竟,这就是它们被称为“局部”变量的原因。

Ruby中有四个局部变量范围:脚本,模块/类定义,方法和块/λ文字。在这四个中,只有块作用域嵌套,只有块可以是闭包。

因此,如果在块中定义局部变量,则它对于该块是本地的。但是,如果在块之外定义一个局部变量,那么它将在块中可用(除非显式声明为块局部变量),因为块作用域嵌套在外部作用域内。在外部范围结束后,它甚至可以在块中使用,因为块范围在其周围的词法环境中关闭。

注意:即使for / in迭代器使用块来消除each的消息,但在此特殊情况下,该块无法获取它自己的范围。避免for / in的另一个原因。

foo = :outerfoo
bar = :outerbar

[nil].each do |*; bar|
  foo = :innerfoo
  bar = :innerbar
  baz = :innerbaz
end

foo #=> :innerfoo
bar #=> :outerbar
baz # NameError: undefined local variable or method `baz' for main:Object

for * in [nil]
  looks_local_but_isnt = :huh
end

looks_local_but_isnt #=> :huh