not instance.group_type.nil? and instance.group_type.downcase == "case"
当第一个表达式为假时,即 group_type 为 nil 时,不会执行后面的第二个表达式。
现在的情况是,group_type 为 nil 时,任然会执行后面的表达式,然后就直接抛异常了“undefined method `downcase' for nil:NilClass”
请问,ruby 中有什么简单的方式 来处理这样的逻辑吗?
puts true and false
puts (true and false)
puts true && false
puts true & false
////~>
true
false
false
false
找到答案了。。。
[1] pry(main)> a = nil
=> nil
[2] pry(main)> not a.nil? and a.downcase
=> false
[3] pry(main)> not a.nil? and a.downcase == 'case'
=> false
[4] pry(main)>
从 Ruby2.3 开始你可以用单身狗运算符了。
a&.downcase == 'case'
题主的思路没错,就是句法太杂了。如果升到了 2.3 就赶紧用楼上的单身狗运算符,没有的话,判断一个对象是否为 nil 在代码中使用它本身就可以了(boolean 类型除外),没必要用 not + nil。
性能上也会有差别,not+nil 编译出来是这样的
0003 opt_send_simple <callinfo!mid:a, argc:0, FCALL|VCALL|ARGS_SKIP>
0005 opt_send_simple <callinfo!mid:nil?, argc:0, ARGS_SKIP>
0007 opt_not <callinfo!mid:!, argc:0, ARGS_SKIP>
0009 dup
0010 branchunless 22
而使用本身来判断只有一句
0003 opt_send_simple <callinfo!mid:a, argc:0, FCALL|VCALL|ARGS_SKIP>
0005 dup
0006 branchunless 18
用 Benchmark 试了下,效率差 30%
user system total real
simple 0.060000 0.000000 0.060000 ( 0.064289)
complex 0.090000 0.000000 0.090000 ( 0.092268)
#14 楼 @dudu_zzzz 基本上就是这个类的方法http://ruby-doc.org/core-2.3.0/RubyVM/InstructionSequence.html
但是这个虚拟机的指令集我找了半天都找不到资料,只有日文资料。貌似 rubyspec 只描述 ruby 语言级行为,关于 ruby 虚拟机怎么实现其实并没有统一标准可循。你要是能找到 MRI 的指令集资料记得告诉我一声。
“Look at this figure…and then…you can see…someone sitting on the floor looking at a dot. On the floor. By themself. Now you don’t forget. Yeah.”
---- yukihiro_matz
irb(main):009:0> class X; attr_accessor :group_type; end
=> nil
irb(main):010:0> instance = X.new
=> #<X:0x007fc43129ae30>
irb(main):011:0> not instance.group_type.nil? and instance.group_type.downcase == "case"
=> false
irb(main):012:0> instance.group_type = 'case'
=> "case"
irb(main):013:0> not instance.group_type.nil? and instance.group_type.downcase == "case"
=> true
irb(main):014:0>
if instance.group_type && instance.group_type.downcase == "case"
这样不就解决了嘛
应该和 and/or 运算符的优先级有关。可以参考下:http://devblog.avdi.org/2014/08/26/how-to-use-rubys-english-andor-operators-without-going-nuts/