范围和块

时间:2015-04-09 14:33:46

标签: ruby scope

在ruby中,moduleclassdef关键字定义了一个新范围。我很困惑为什么块中定义的局部变量不存在于块之外。块参数是另一个范围门吗?例如:

(1..2).each { |n| numer = 'czesc' }
numer # => NameError: undefined local variable or method `czesc' for main:Object

或更简单:

def kon; end
kon { kot = 3 }
kot # => NameError: undefined local variable or method `kot' for main:Object

我想,也许它不是持久化的,因为它是在方法的参数中定义的,但是以下适用于普通参数:

def pokaz(cos)
  p cos
end
pokaz(co = "to")
co # => "to"

2 个答案:

答案 0 :(得分:4)

您可能会考虑Proc类的惰性实例中的代码块。

您使用kon / kot的第二个示例实际上并不是您所期望的。您为函数kon提供了一个代码块。除非已请求,否则不会评估此代码块 。在您的代码段中,它永远不会被评估。看:

▶ def kon; end
#⇒ :kon
▶ kon { puts 'I am here' }
#⇒ nil

您传递了一个代码块。精细。现在kon应该根据需要调用它:

▶ def kon; yield ; end
#⇒ :kon
▶ kon { puts 'I am here' }
# I am here
#⇒ nil

当您将代码块传递给each实例的Enumerator方法时:

(1..2).each { |n| numer = 'czesc' }

正在对此Enumerator的上下文中评估代码块。但默认接收器self仍然是主线程。这使得代码块主要像闭包一样(它们可以访问调用者绑定):

▶ kot = 10  
#⇒ 10
▶ 5.times do |i|  
▷   kot = i  
▷ end      
▶ puts kot
#⇒ 4

希望它有所启发。

答案 1 :(得分:1)

  

在ruby中,moduleclassdef个关键字定义了一个新的范围。

Ruby中有六个范围构造:模块体,类体,方法体和脚本体创建新的范围,块体和" stabby lambda"文字体创建新的嵌套范围。

  

我很困惑为什么块中定义的局部变量不存在于块之外。

因为块体有自己的词法范围。范围是嵌套的,这意味着它可以从外部作用域访问局部变量,但内部作用域中的变量永远不会泄漏到外部作用域。