范围和块

在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" 

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

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

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

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

您可能会考虑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 

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

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

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

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

希望它有所启发。