Ruby:安全导航操作符,未定义方法`call`

Eth*_*ent 3 ruby safe-navigation-operator

我试图比较一个数字文字与可以返回的函数的返回值nil或数字.考虑一下:

def unreliable
  [nil, 42].sample  
end

unreliable > 10
Run Code Online (Sandbox Code Playgroud)

这将占50%的时间NoMethodError: undefined method '>' for nil:NilClass.所以我尝试了这个:

unreliable&.(:>, 10)
Run Code Online (Sandbox Code Playgroud)

这种方法可以保证nil我的预期,但是在unreliable返回时我得到了这个42:

NoMethodError: undefined method `call' for 42:Fixnum
Run Code Online (Sandbox Code Playgroud)

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

foo = unreliable
foo && foo > 10
Run Code Online (Sandbox Code Playgroud)

但有使用安全导航运营商,数字和方式:>,:<,:==,:+,:-,:/,:*,等?


编辑:Numeric在我的问题中,重点是红鲱鱼.请参阅@Jörg的回答.我把Rails的try语法与安全导航操作符的语法混淆了.

Eri*_*nil 5

这在Ruby 2.3+中运行良好:

unreliable&.> 10
Run Code Online (Sandbox Code Playgroud)

例如 :

[-5, 0, nil, 5].each do |unreliable|
  p unreliable&.> 0
end
# false
# false
# nil
# true
Run Code Online (Sandbox Code Playgroud)

你尝试它的方式,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]
Run Code Online (Sandbox Code Playgroud)

使用安全导航操作符,不需要放置parens,方法应该是方法名称,而不是符号(Rails' try需要符号).