Bug #13815
closedp args
Description
x=y=0 # outside defined vars!
3.times {|i| x,y=x+1,y+1 } # as expected: x==3
3.times {|i| p(x,y=x+1,y+1) } # NOT as expected: x not changed!
x,y are the same vars as above. p shoudn't have any effect on scope¶
Updated by opti (Andreas Opti) about 7 years ago
- Subject changed from p changes scope of vars to p changes scope of *vars
x=y=0 # outside defined vars!
3.times { x,y = x+1,y+1 } # as expected: x==3
3.times { p(x,y = x+1,y+1) } # NOT as expected: x not changed!
x,y are the same vars as above. p shoudn't have any effect on scope¶
Updated by jeremyevans0 (Jeremy Evans) about 7 years ago
- Status changed from Open to Rejected
opti (Andreas Opti) wrote:
x=y=0 # outside defined vars!
3.times { x,y = x+1,y+1 } # as expected: x==3
3.times { p(x,y = x+1,y+1) } # NOT as expected: x not changed!x,y are the same vars as above. p shoudn't have any effect on scope¶
This makes sense once you understand how ruby parses the p method call:
3.times { p((x),(y = x+1),(y+1)) }
If you want the same behavior, you need to use parentheses:
3.times { p((x,y = x+1,y+1)) }
Updated by opti (Andreas Opti) about 7 years ago
- Subject changed from p changes scope of *vars to p args
- Status changed from Rejected to Open
- ruby -v changed from 2.4 and 2.5 to 2.5.x
If you want the same behavior, you need to use parentheses:
3.times { p((x,y = x+1,y+1)) }
ok, but also with ((...)) [most people] would assume its meaning is (x, y=x+1, y+1)...¶
*Other example:
p(x+=1,x+=1) # ok
p (x+=1,x+=1) # error
p ((x,y)=[x+1,y+1]) # ok
p((x,y)=[x+1,y+1]) # ERROR! --- normally there should be NO space before (....)
So the parsing of p(Args) might be improved...
Updated by phluid61 (Matthew Kerwin) about 7 years ago
opti (Andreas Opti) wrote:
If you want the same behavior, you need to use parentheses:
3.times { p((x,y = x+1,y+1)) }ok, but also with ((...)) [most people] would assume its meaning is (x, y=x+1, y+1)...¶
Most people wouldn't write it in the first place.
You could, if you really, really wanted to do a multiple assignment and capture the result into an array and p
the array, all in one step.
I don't think it's a parser issue, though; the parser does a logical thing at each step. It's the author who's doing something weird.
*Other example:
p(x+=1,x+=1) # ok
p (x+=1,x+=1) # error
Well, yeah, but this is well known, well defined ruby. p(x)
is an unambiguous function call; p (x)
is a parenthesised (x)
being passed as the first positional argument to p
.
It might help illustrate by replacing the p
function call with, say, an assignment:
#p(x)
a = x
#p((x))
a = (x)
#p x
a = x
#p (x)
a = (x)
#p (x+=1,x+=1)
a = (x+=1,x+=1) #???
#p ((x,y)=[x+1,y+1])
a = ((x,y)=[x+1,y+1])
# Note: multiple assignment returns the whole array, so a == [x,y]
# This can also be written: a = (x,y=[x+1,y+1]) or: a = (x,y=x+1,y+1)
#p((x,y)=[x+1,y+1])
a = (x,y)=[x+1,y+1] #??? This part doesn't make sense: a = (x,y)
So the parsing of p(Args) might be improved...
I don't like saying this, but I think this is a case where you have to get familiar with ruby's syntax. It all makes sense once you understand how the parser sees what you've written.
Updated by matz (Yukihiro Matsumoto) about 7 years ago
- Status changed from Open to Closed
Andreas, it's easy to say "might be improved", but without the concrete design, it's worth nothing for us.
We designed for reasons, with the balance of features. Please submit the proposal, if you come up with the new idea.
Matz.