Project

General

Profile

Bug #13815

p args

Added by opti (Andreas Opti) about 2 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:82380]

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

History

Updated by opti (Andreas Opti) about 2 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 2 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 2 years ago

  • ruby -v changed from 2.4 and 2.5 to 2.5.x
  • Status changed from Rejected to Open
  • Subject changed from p changes scope of *vars to p args

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 2 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 2 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.

Also available in: Atom PDF