Precedence of -@ and +@
+@ seem to have issues with method chaining:
i = 5 -i.negative? # NoMethodError (undefined method `-@' for false:FalseClass)
here's another example:
# frozen_string_literal: true +'foo'.upcase! # FrozenError (can't modify frozen String)
I know that I can fix this by adding parentheses, i.e.
(+'foo').upcase! but it feels cumbersome.
Shouldn't the above work out of the box?
Unless I'm missing a crucial use case, the precedence for
+@ should be changed.
Updated by sos4nt (Stefan Schüßler) 8 months ago
nobu (Nobuyoshi Nakada) wrote:
Do you expect
i = -1; -i.absto return
Yes, indeed. I'd expect
<something>.abs to return a positive value.
1.abs #=> 1 -1.abs #=> 1 i = 1 i.abs #=> 1 -i.abs #=> -1 <- not what I'd expect
i = 1 -1.succ #=> 0 -i.succ #=> -2 <- not what I'd expect
And a really weird one:
i = 1 -i.to_s #=> "1" <- this is a frozen string
Again, I perfectly understand why this is happening and how to avoid it. I just don't think this is the way it should be, nor do I see why it could be preferable.
Updated by spinute (Satoru Horie) 8 months ago
Compatibility is essential in Ruby. So, we need strong evidence when we break it.
I do not think the current behavior is weird.
<something>.abs returns positive value, consistently.
A programmer who knows
-i.abs is evaluated as
-(i.abs) can get an expected result. As a note,
-1 is not an operator, so
-1.abs == (-1).abs == 1.
-i.to_s is also explained in the same way.
I agree that the behavior may be confusing for beginners.