锁定老帖子 主题:nil的疑惑
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-02-27
所以,a = {:x => 1},则a[:y] == nil,成立,真好。 反过来成立吗?就是说: 如果a = {:x => 1, :y => nil},则a == {:x => 1} 结果:不成立。 为什么?!真想掐死它。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-02-27
不成立是很正常的,a = {:x => 1, :y => nil}已经显式定义了一对pair (:y => nil),nil在这里是这对pair的value。返过来a = {:x => 1},则a[:y] == nil,这里的a并没有:y这个key,所以返回空值nil。
|
|
返回顶楼 | |
发表时间:2007-02-28
这个问题我就有想法了,我觉得反推如果不成立的话,从逻辑上讲,不是很舒服,因为nil就是没有。当然这也跟我的一次编码遭遇有关,比如,一个比较普遍的做法:
default_options = {:a => 1, :b => 1} options = default_options.merge user_options 我直觉上会认为这段代码没问题,而且挺优雅的。但是,如果: user_options = {:a => params[:a], :b => params[:b]} 而恰好这时params[:b] = nil, options就会变成:{:a => 1, :b => nil} 结果default_options就完全失去了意义。 我看到不少这样的写法,如果不小心就出错啦。 |
|
返回顶楼 | |
发表时间:2007-02-28
nil不是没有,也是个对象
用options = default_options.merge(user_options) {|k,o,n| n || o} |
|
返回顶楼 | |
发表时间:2007-02-28
你定义的是a = {:x => 1, :y => nil} ,那么你知道你的a现在是什么类型了吗?一个hash表
|
|
返回顶楼 | |
发表时间:2007-02-28
然后你用a == {:x => 1} 去比较,为什么是false? 因为{:x => 1}是另外一个hash表。
你的问题不是逻辑问题,而是概念没有搞清楚。 |
|
返回顶楼 | |
发表时间:2007-02-28
唉,逻辑就是逻辑。概念是定义出来的,想怎么定义都行,但不是定义出来的概念就一定符合逻辑。
|
|
返回顶楼 | |
发表时间:2007-02-28
njmzhang 写道 nil不是没有,也是个对象
这句话已经足以回答楼主的“为什么?” |
|
返回顶楼 | |
发表时间:2007-02-28
嗯,是这样的,nil是对象,这是定义的规则和具体实现方式。我指的是{:x=>1}[:y]是nil,这个定义我理解,但这个逻辑我不太喜欢,因为反之就不成立。
要知道,那个default_options的例子是我看到很多人都这么用的,但里面隐含的陷阱却未必很多人了解,这就增加了犯错的几率。反正我学ruby基本上是一个在不断犯错中学习的过程,作为一个编了十几年程序的人来说,这是过去学一门新语言时比较少见的情况。老啦:-) |
|
返回顶楼 | |
发表时间:2007-02-28
dcaoyuan 写道 这个问题我就有想法了,我觉得反推如果不成立的话,从逻辑上讲,不是很舒服,因为nil就是没有。当然这也跟我的一次编码遭遇有关,比如,一个比较普遍的做法:
default_options = {:a => 1, :b => 1} options = default_options.merge user_options 我直觉上会认为这段代码没问题,而且挺优雅的。但是,如果: user_options = {:a => params[:a], :b => params[:b]} 而恰好这时params[:b] = nil, options就会变成:{:a => 1, :b => nil} 结果default_options就完全失去了意义。 我看到不少这样的写法,如果不小心就出错啦。 it's not about nil, it's about Hash. "Two hashes are equal if they each contain the same number of keys and if each key-value pair is equal to (according to Object#==) the corresponding elements in the other hash." -- RDoc of Hash user_options = Hash.new user_options[:a] = params[:a] if params[:a] user_options[:b] = params[:b] if params[:b] |
|
返回顶楼 | |