Reputation: 11803
I'm new to Ruby and I'm completely disgusted. Why does the following code:
def some_method(v=1) 10*v end
puts (some_method (1).next)
puts some_method (1).next
Evaluate to:
20
11
Upvotes: 2
Views: 188
Reputation: 20125
In Ruby 1.8.7, the first example evaluates to 20, because that is the correct behavior.
Let's break it down. We start with
puts (some_method (1).next)
We then add the missing/implicit parentheses:
puts((some_method((1).next)))
Let's split this out a bit into its separate parts:
puts(
(
some_method(
(1).next
)
)
)
Ruby starts from the inside, evaluating (1)
. The value of that is, well, 1
, so we get
puts(
(
some_method(
1.next
)
)
)
Next up, 1.next
, which returns 2
:
puts(
(
some_method(
2
)
)
)
Thus, Ruby passes 2
as the parameter to some_method
, which then multiplies by 10 and returns the correct value, 20
:
puts(
(
20
)
)
This - unsurprisingly outputs 20
.
What you probably wanted to write is
puts some_method(1).next
which outputs 11
. The space you've added between the method name and the parenthesis is significant.
Interestingly, if you are indeed running 1.8.7, you actually get a warning in that last example of yours:
>> puts some_method (1).next
(irb):13: warning: don't put space before argument parentheses
11
=> nil
Upvotes: 5
Reputation: 11638
Under jruby-1.6.7.2 in ruby 1.8 compatibility mode, I see:
20
11
Whereas in 1.9 compatibility mode I see
20
20
I suspect that there was a change to the precedence operators.
Upvotes: 1
Reputation: 4375
# first case
puts (some_method (1).next)
=> through the () around some_method (1).next everything gets wrapped into the puts.
some_method (1).next => (1).next => 2 => 2*10 => 20
# second case
puts some_method (1).next
=> here is no "wrapper" around the puts
some_method (1).next => 1*10 => 10 => 10.next => 11
UPDATE: (ruby 1.9.2-p290)
Interesting difference between "with space" and "without space" (okay, that´s no answer, that´s another question I think :))
irb(main):011:0> puts some_method (1).next
20
=> nil
irb(main):012:0> puts some_method(1).next
11
=> nil
Upvotes: 1