赞 | 13 |
VIP | 118 |
好人卡 | 28 |
积分 | 12 |
经验 | 35779 |
最后登录 | 2017-7-6 |
在线时间 | 1564 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1210
- 在线时间
- 1564 小时
- 注册时间
- 2008-7-30
- 帖子
- 4418
|
本帖最后由 DeathKing 于 2011-9-30 22:28 编辑
你的代码是在块(block)中定义了一个test变量,而这个变量的生命周期就只存在于块中。考虑下面代码:- 10.times do
- i = "Ditro am i"
- end
- p i # <<- 此处发生NameError。
复制代码 正确的写法如下:- # 预先初始化此变量
- i = "no who"
- 10.times do
- i = "Ditro am i"
- end
- p i # Ditro am i
复制代码 按照我们的预期,你的脚本应该发生NameError,但为什么你的脚却发生了ArgumentError呢?事实上,test是由Kernel模块提供的一个方法,原型如下:- test(int_cmd, file1 [, file2] )
复制代码 不用去考察test方法的实际意义,你只需要知道,test方法需要至少2个参数。而你的脚本中使用了一个“短命”的test变量,在10.times的迭代后,此变量随即消失了。因此,当使用p (test)的时候,test并不是你所期望的变量,而是Kernel类的那个方法,这是Ruby中的一个陷阱,Ruby中的诗歌模式允许你调用方法时不加上括号,这使得你区分一个变量和方法不甚容易。
解决方法异常简单,在进行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这个神奇的东西~~
排版党出没……再次整理中���
��� |
评分
-
查看全部评分
|