3

我正在尝试将数字文字与可以返回的函数的返回值nil或数字进行比较。考虑一下:

def unreliable
  [nil, 42].sample  
end

unreliable > 10

这将在 50% 的时间内爆炸NoMethodError: undefined method '>' for nil:NilClass。所以我尝试了这个:

unreliable&.(:>, 10)

这种方法可以达到nil我的预期,但是当我unreliable返回时我得到了这个42

NoMethodError: undefined method `call' for 42:Fixnum

我怀疑这与每个只允许一个实例存在的怪癖有关Numeric,请参见此处。我知道我可以做到这一点:

foo = unreliable
foo && foo > 10

但是有没有办法将安全导航运算符与数字 and :>, :<, :==, :+, :-, :/,:*等一起使用?


编辑:我的问题的重点Numeric是红鲱鱼。请参阅@Jörg 的回答。我将 Rails 的try语法与安全导航运算符的语法混淆了。

4

2 回答 2

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]

使用安全导航运算符,不需要放置括号,方法应该是方法名称,而不是符号(Railstry需要符号)。

于 2017-04-20T16:38:52.770 回答
0

我怀疑这与只允许每个实例存在一个实例的怪癖有关Numeric

不,这与那一点关系都没有。

foo.(bar)

是语法糖

foo.call(bar)

因此,

foo&.(bar)

是语法糖

foo&.call(bar)

所以,你的代码:

unreliable&.(:>, 10)

是语法糖

unreliable&.call(:>, 10)

我不确定谁告诉你安全导航运算符将消息作为符号参数。&安全导航运算符的全部意义在于,通过在 前面添加单个字符,您只需要微不足道的语法开销,.否则表达式不会改变。

所以,

unreliable > 10

这与

unreliable.>(10)

简单地变成

unreliable&.>(10)
于 2017-04-20T19:12:20.653 回答