`

Ruby中的block与变量作用域

阅读更多

按照我们一般的思维模式,特别是在大量使用了Java等高级强静态语言后,可能对变量作用域有很好的理解。

但是在Ruby中,我们会发现一些不同往常经验的例子。

系统环境 写道
ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
 

请看这个例子:

#test the block

verb='rescued'
['sedated', 'powdered', 'electrocuted'].
each do |verb|
  puts 'Dr. Cham ' + verb + ' his niece Hannah.'
end
puts 'Yes, Dr. Cham ' + verb + ' his niece Hannah.'
if true then
  verb = 'In the if'
end
puts 'After the if-then-end statement ' + verb

 首先我们不运行,来人为想像一下这个的输出,深深都到Java影响的话可能会得到这样一个结果:

猜想的结果 写道
Dr. Cham sedated his niece Hannah.
Dr. Cham powdered his niece Hannah.
Dr. Cham electrocuted his niece Hannah.
Yes, Dr. Cham rescued his niece Hannah.
After the if-then-end statement In the if

 那么让我们来运行一下看看真实的情况:

真实输出 写道
Dr. Cham sedated his niece Hannah.
Dr. Cham powdered his niece Hannah.
Dr. Cham electrocuted his niece Hannah.
Yes, Dr. Cham electrocuted his niece Hannah.
After the if-then-end statement In the if

 很奇怪吧,从感觉上,虽然我们在各个block中定义了局部变量,但是从表现上来看始终就一个变量在工作。其实也不是,看看这个例子的简单变形(就去掉了第一行的代码):

#test the block

#verb='rescued'
['sedated', 'powdered', 'electrocuted'].
each do |verb|
  puts 'Dr. Cham ' + verb + ' his niece Hannah.'
end
puts 'Yes, Dr. Cham ' + verb + ' his niece Hannah.'
if true then
  verb = 'In the if'
end
puts 'After the if-then-end statement ' + verb

 输出发生了变化:

输出结果 写道
Dr. Cham sedated his niece Hannah.
Dr. Cham powdered his niece Hannah.
Dr. Cham electrocuted his niece Hannah.
testblock.rb:8: undefined local variable or method `verb' for main:Object (NameError)

 也就是说,那个block还是起了一些作用的。

也就是说,如果block意识到verb已经存在,然后就直接使用了。

小结:

  • 变量仍然有生存周期
  • block块 会去使用已经存在的同名的变量

 

有机会,我会好好研究下《Ruby Hacking Guide》,认真分析一下原因的。

谢谢各位朋友的提示,今天我将ruby升级到了1.9版。

ubuntu apt-get 写道
sudo apt-get install ruby1.9 irb1.9 rdoc1.9

 现在的系统环境

系统环境 写道
ruby 1.9.0 (2007-12-25 revision 14709) [i486-linux]

 现在重新运行一下看看结果:

运行结果 写道
Dr. Cham sedated his niece Hannah.
Dr. Cham powdered his niece Hannah.
Dr. Cham electrocuted his niece Hannah.
Yes, Dr. Cham rescued his niece Hannah.
After the if-then-end statement In the if

 确实已经恢复到期望输出了。

再次感谢。

分享到:
评论
2 楼 Jan 2008-11-30  
根本就是1.8的bug,楼主不用研究了。。。
1 楼 nan1nan1 2008-11-29  
matz承认这是ruby设计上的失误,1.9就不这样了。

相关推荐

    深入讲解Ruby中Block代码快的用法

    当Block参数与外部作用域中的局部变量同名时,Block参数将覆盖外部变量。例如: ```ruby value = "someshape" [1, 2].each { |value| puts value } puts value # 输出结果为:1, 2, someshape ``` 为了确保Block内...

    ruby中文教程(源代码)

    - 函数与方法:Ruby中的函数被称为方法,可以定义在类或模块中,支持块(block)和 Proc 对象。 2. **面向对象编程(OOP)** - 类与对象:Ruby是纯面向对象的语言,一切皆对象。你可以创建自定义类来封装数据和...

    ruby语言帮助文档(简体中文)

    块可以与方法一起使用,形成闭包,这样就可以在方法中捕获并操作外部作用域的变量。 6. **元编程**:Ruby的元编程能力非常强大,允许在运行时修改和创建类和对象。这得益于Ruby的反射API和`send`方法,可以动态地...

    ruby基础教程中文第四版

    理解它们的作用域和使用方式是掌握Ruby语法的关键。 2. **数据类型**:Ruby支持多种数据类型,如整数、浮点数、字符串、布尔值、数组、哈希等。特别是哈希,它是一种键值对集合,具有灵活的操作方式。 3. **控制...

    Ruby语言中文教程

    理解它们的作用域和用法是学习Ruby的基础。 - 数据类型:包括字符串(`String`)、数字(`Integer`和`Float`)、布尔值(`TrueClass`和`FalseClass`)、数组(`Array`)、哈希(`Hash`)等。 - 控制结构:如条件...

    Ruby In a Nutshell

    - 闭包是指能够访问其定义时作用域的变量的块,即使在块被调用时该作用域已不存在。 8. ** Proc和Lambda** - `Proc`和`lambda`都是Ruby的代码对象,可以存储和传递代码。 - `Proc`更灵活,允许在块末尾隐式返回...

    ruby for rails

    4. **The default object (self) and scope**:Ruby中的`self`关键字,它如何指示方法调用的目标对象,以及作用域规则,包括局部作用域、实例作用域和类作用域。 5. **Control flow techniques**:控制流程的技巧,...

    Prorammer ruby 语法截图

    - Ruby有严格的局部作用域,变量在定义它的代码块内可见。 13. **元编程** - Ruby允许在运行时动态修改类和对象,这是其强大的元编程能力。 以上只是《Prorammer Ruby》中部分关键知识点的概述。深入学习这本书...

    Ruby常见面试题.pdf

    变量名区分大小写,并且以特定字符开头来表示其作用域: - **局部变量**:以小写字母或下划线开头。 - **实例变量**:以`@`开头。 - **类变量**:以`@@`开头。 - **全局变量**:以`$`开头。 **示例**: ```ruby # ...

    详解Ruby中的块的知识

    ### 详解Ruby中的块的知识 在Ruby编程语言中,“块”是一种非常强大的功能,它能够让你以更加灵活的方式处理各种编程任务。本文将详细介绍Ruby中的块及其相关概念,包括`yield`语句、`BEGIN/END`块以及如何在方法中...

    ruby初学者教程(对初学者很有帮助)

    - **局部变量**:以小写字母或下划线开头的变量,作用域限于当前块。 - **实例变量**:以`@`开头的变量,属于特定对象,可以在该对象的任何方法中访问。 - **类变量**:以`@@`开头的变量,属于整个类,可以在该类的...

    Ruby语言开发教程与案例.zip

    4. **闭包**:Ruby的Proc和Lambda都是闭包,能够记住其定义时的作用域,即使在其他作用域中使用也能访问到。 5. **Gem和库**:Ruby的生态中有大量的开源库(Gem),如Rails用于Web开发,ActiveRecord处理数据库操作...

    有关Ruby入门文章

    它们各自的作用域不同,使用时需注意。 2. 控制结构:Ruby支持常见的控制结构,如if/else、unless、case、while、for以及循环控制语句如break、next等。 3. 函数定义:Ruby使用`def`关键字定义函数,函数名后跟...

    Ruby程序设计.rar

    8. **闭包和上下文**:Ruby中的闭包(Closure)是能够记住其被定义时的作用域的函数,这是理解块、Proc和Lambda的关键。 9. **迭代器和集合操作**:Ruby提供了许多方便的集合操作,如map、each、select等,以及枚举...

    Ruby 入门教程和程序

    每种变量的作用域和生命周期都有所不同,理解和掌握这些将帮助你编写更清晰的代码。 Ruby的控制结构包括条件语句(如if、unless、case)和循环(如for、while、until、each)。Ruby的块(block)和Proc对象是其独特...

    ruby语言入门教程(中文版)[PDF]

    Ruby还支持闭包,这是通过块、Proc和Lambda实现的,使得函数能够记住其定义时的作用域。 Ruby的标准库非常强大,包含了大量实用的模块,如文件操作、网络通信、正则表达式、日期和时间处理等。Ruby还有强大的元编程...

    ruby准备资料ruby准备资料

    闭包是Ruby中的一种重要特性,它结合了函数和变量的作用域。一个闭包可以记住其创建时的作用域,即使该作用域已经不再存在。这使得闭包能够访问并修改其外部环境中的变量,即使在函数返回后仍然有效。在Ruby中,块...

    Ruby编程语言简介,资源由网络分享整理,如有侵权请联系我

    1. **变量**:Ruby中的变量分为五种类型,分别是局部变量(以小写字母或下划线开头)、实例变量(以`@`开头)、类变量(以`@@`开头)、全局变量(以`$`开头)和常量(以大写字母开头)。它们各自有不同的作用域和...

Global site tag (gtag.js) - Google Analytics