| 
 
| 赞 | 13 |  
| VIP | 118 |  
| 好人卡 | 28 |  
| 积分 | 13 |  
| 经验 | 35779 |  
| 最后登录 | 2017-7-6 |  
| 在线时间 | 1564 小时 |  
 Lv3.寻梦者 
	梦石0 星屑1305 在线时间1564 小时注册时间2008-7-30帖子4418 
 | 
| 本帖最后由 DeathKing 于 2011-9-30 22:28 编辑 
 你的代码是在块(block)中定义了一个test变量,而这个变量的生命周期就只存在于块中。考虑下面代码:
 正确的写法如下:复制代码10.times do 
  i = "Ditro am i"
end
p i  # <<- 此处发生NameError。
按照我们的预期,你的脚本应该发生NameError,但为什么你的脚却发生了ArgumentError呢?事实上,test是由Kernel模块提供的一个方法,原型如下:复制代码# 预先初始化此变量
i = "no who"
10.times do 
  i = "Ditro am i"
end
p i  # Ditro am i
不用去考察test方法的实际意义,你只需要知道,test方法需要至少2个参数。而你的脚本中使用了一个“短命”的test变量,在10.times的迭代后,此变量随即消失了。因此,当使用p (test)的时候,test并不是你所期望的变量,而是Kernel类的那个方法,这是Ruby中的一个陷阱,Ruby中的诗歌模式允许你调用方法时不加上括号,这使得你区分一个变量和方法不甚容易。复制代码test(int_cmd, file1 [, file2] ) 
 解决方法异常简单,在进行10次迭代前显式的初始化一下test变量,不过最好使用一个其他名字,比如my_test。
 
 提供一个简单的方法检测我的陈述,重定义Kernel#test方法:
 将此代码插入到你错误代码之前,再次运行错误的代码,看看结果吧!复制代码module Kernel
  def test
    p "You call the test method in Kernel module! "
  end
end
 
 拾遗
 
 我们假设除了Kernel定义的test方法以外,在当前的上下文(Context)中没有其他定义的test方法了。此时,环境中存放有一个test变量和Kernel#test()方法(图中并没有显式的注明括号)。
 
 当第一次调用test时,因为没有括号,Ruby会认为你调用的是一个变量,的确可以在内存中找到这个变量,一切Okay。迭代结束后,变量消失。此时环境中只有Kernel#test方法。
 
 第二次调用test,Ruby也会认为是变量(因为没有显式的加上括号),但并没有找到对应变量,Ruby便认为你是用了“诗歌模式”,因此调用Kernel#test方法。而Kernel#test方法要求传递至少2个参数,至此,错误便产生了。
 
 
 参考资料:
 [1]: http://szsu.wordpress.com/2010/09/07/continuation/
 [2]: http://szsu.wordpress.com/2010/09/04/binding/
 [3]: http://deathking.is-programmer.com/posts/29141.html
 
 前两个是我老板的文章,末一个是我搬过来的,如果wordpress的网页不能访问请访问第三个……感谢老板曾经给我将结果banding这个神奇的东西~~
 排版党出没……再次整理中���
 ���
 | 
 评分
查看全部评分
 |