我正在尝试将数字文字与可能返回nil
或数字的函数的返回值进行比较。考虑一下:
def unreliable
[nil, 42].sample
end
unreliable > 10
NoMethodError: undefined method '>' for nil:NilClass
这将占50%的时间。所以我尝试了这个:
unreliable&.(:>, 10)
我希望nil
保护这种方法,但是当unreliable
返回42
时,我会得到此信息:
NoMethodError: undefined method `call' for 42:Fixnum
我怀疑这与每个Numeric
只允许一个实例存在的怪癖有关,请参阅here。而且我知道我可以这样做:
foo = unreliable
foo && foo > 10
但是有没有办法将安全导航操作符与数字和:>
,:<
,:==
,:+
,:-
,{{一起使用1}},:/
等?
修改:在我的问题中对:*
的关注是一个红色的鲱鱼。请参阅@Jörg的回答。我把Rails的Numeric
语法与安全导航操作符的语法混淆了。
答案 0 :(得分:5)
这在Ruby 2.3+中运行良好:
unreliable&.> 10
例如:
[-5, 0, nil, 5].each do |unreliable|
p unreliable&.> 0
end
# false
# false
# nil
# true
你尝试它的方式,Ruby希望unreliable
是一个可调用的对象,例如Proc
:
unreliable = Proc.new{ |*params| puts "unreliable has been called with #{params}" }
unreliable&.(:>, 10)
# unreliable has been called with [:>, 10]
unreliable.call(:>, 10)
# unreliable has been called with [:>, 10]
unreliable&.call(:>, 10)
# unreliable has been called with [:>, 10]
unreliable[:>, 10]
# unreliable has been called with [:>, 10]
使用安全导航操作符,不需要放置parens,方法应该是方法名称,而不是符号(Rails'try
需要符号)。
答案 1 :(得分:0)
我怀疑这与每个
只允许一个实例存在的怪癖有关Numeric
不,这与此毫无关系。
foo.(bar)
是
的语法糖foo.call(bar)
Ergo,
foo&.(bar)
是
的语法糖foo&.call(bar)
所以,你的代码:
unreliable&.(:>, 10)
是
的语法糖unreliable&.call(:>, 10)
我不确定是谁告诉你安全导航操作员将消息作为符号参数。安全导航操作符的重点在于,通过在&
前添加单个字符.
,您只需要轻微的语法开销,否则表达式将保持不变。
所以,
unreliable > 10
与
相同unreliable.>(10)
简单地变成
unreliable&.>(10)