I am trying to compare a number literal with the return value of a function that could return nil
or a numeric. Consider this:
def unreliable
[nil, 42].sample
end
unreliable > 10
This will blow up 50% of the time with NoMethodError: undefined method '>' for nil:NilClass
. So I tried this:
unreliable&.(:>, 10)
That approach does the nil
guarding I expect, but I get this when unreliable
returns 42
:
NoMethodError: undefined method `call' for 42:Fixnum
I suspect this has to do with the quirks of allowing only one instance to exist for each Numeric
, see here . And I know I can do this:
foo = unreliable
foo && foo > 10
But is there a way to use the safe navigation operator with a numeric and :>
, :<
, :==
, :+
, :-
, :/
, :*
, etc?
Edit : The focus on Numeric
in my question is a red herring. See @Jörg's answer. I was confusing Rails's try
syntax with the safe-navigation operator's syntax.
This works fine in Ruby 2.3+ :
unreliable&.> 10
For example :
[-5, 0, nil, 5].each do |unreliable|
p unreliable&.> 0
end
# false
# false
# nil
# true
The way you tried it, Ruby expects unreliable
to be a callable object such as a 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]
With the safe-navigation operator, there's no need to put parens and the method should be a method name, not a symbol (Rails' try
expects a symbol).
I suspect this has to do with the quirks of allowing only one instance to exist for each
Numeric
No, this has nothing to do with that at all.
foo.(bar)
is syntactic sugar for
foo.call(bar)
Ergo,
foo&.(bar)
is syntactic sugar for
foo&.call(bar)
So, your code:
unreliable&.(:>, 10)
is syntactic sugar for
unreliable&.call(:>, 10)
I'm not sure who told you that the safe-navigation operator takes the message as a symbol argument. The whole point of the safe-navigation operator is that you only have trivial syntactic overhead by adding a single character, the &
in front of the .
, and the expression is otherwise unchanged.
So,
unreliable > 10
which is the same as
unreliable.>(10)
simply becomes
unreliable&.>(10)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.