Using trailing rescue makes me cringe because it can hide problems with the underlying code because it is an Exception trap and not an ArgumentError, which can lead to unsuccessful conversion attempts. This is not so concise, but it should handle the corresponding exception:
def convert(input) value = begin Integer(input) rescue ArgumentError nil end value ||= begin Float(input) rescue ArgumentError nil end value ||= begin Rational(input) rescue ArgumentError nil end value end convert('1')
Thinking about it, it looks like it could be DRY'd before:
def convert(input) [:Integer, :Float, :Rational].each do |m| begin return Kernel.method(m).call(input) rescue ArgumentError end end nil end convert('1')
As Jorn pointed out, the above was not a good example. I used Kernel to access Integer()
, Float()
and Rational
, because where they are defined, but in fact Object was the place to search, since it inherits from the kernel.
And this was one of those days when I knew that there was a good way to name a method indirectly, but call
was in my mind, not send
, as Stefan pointed out. So here is a cleaner way to do this, starting with:
return Object.send(m, input)
But this can be reduced to:
return send(m, input)
as a result of:
def convert(input) [:Integer, :Float, :Rational].each do |m| begin return send(m, input) rescue ArgumentError end end nil end convert('1')