Bug #21029
closedPrism behavior for `defined? (;x)` differs
Added by qnighy (Masaki Hara) 10 months ago. Updated 4 months ago.
Description
Prism has a different behavior for (;expr) when used in defined? predicate:
% ./miniruby --parser=prism -e "p defined? (;x)"
nil
% ./miniruby --parser=parse.y -e "p defined? (;x)"
"expression"
Although not a significant difference, aligning either of them with the other would be better.
Updated by kddnewton (Kevin Newton) 10 months ago
Actions
#1
[ruby-core:120624]
- Assignee set to prism
Updated by kddnewton (Kevin Newton) 10 months ago
Actions
#2
[ruby-core:120673]
I think we should change parse.y to match this behavior. I will ask around.
Updated by hsbt (Hiroshi SHIBATA) 9 months ago
Actions
#3
- Status changed from Open to Assigned
Updated by matz (Yukihiro Matsumoto) 9 months ago
Actions
#4
[ruby-core:120966]
I think compound expressions (expressions (including empty) concatenated by semicolons) should be “expression” as parse.y.
It makes defined? simpler. I know the current defined? behavior recursively check for defined-ness (e.g., method parameters), I don't think we need that complexity here.
Matz.
Updated by qnighy (Masaki Hara) 9 months ago
Actions
#5
[ruby-core:120968]
I think compound expressions (expressions (including empty) concatenated by semicolons) should be “expression” as
parse.y.
Interestingly enough though:
% ruby --parser=prism -e "p defined? (x;)"
nil
% ruby --parser=parse.y -e "p defined? (x;)"
nil
% ruby --parser=prism -e "p defined? (;x)"
nil
% ruby --parser=parse.y -e "p defined? (;x)"
"expression"
Updated by kddnewton (Kevin Newton) 9 months ago
Actions
#6
[ruby-core:120988]
@matz (Yukihiro Matsumoto) for what it's worth, it makes it much more complicated in the Prism compiler because we don't have empty statements. So it's not a recursive situation at the moment, it's just a single statement.
As @qnighy points out, should this be "expression" for when there is a trailing ;?
Updated by mame (Yusuke Endoh) 8 months ago
Actions
#7
[ruby-core:121329]
Discussed at the dev meeting.
kddnewton (Kevin Newton) wrote in #note-6:
As @qnighy points out, should this be "expression" for when there is a trailing
;?
@matz (Yukihiro Matsumoto) said "yes"; defined? (x;) should also return "expression".
Updated by kddnewton (Kevin Newton) 7 months ago
Actions
#8
[ruby-core:121401]
I have updated Prism with https://github.com/ruby/ruby/commit/adaaa7878ebee62888bf3547d14c1db4938da88a, but the added test fails for parse.y. I haven't had a chance to look at it yet, but maybe someone else with more familiarity could.
Updated by kddnewton (Kevin Newton) 7 months ago
Actions
#9
[ruby-core:121402]
- Assignee deleted (
prism)
Updated by kddnewton (Kevin Newton) 7 months ago
Actions
#10
- Status changed from Assigned to Closed
Applied in changeset git|adaaa7878ebee62888bf3547d14c1db4938da88a.
Handle void expressions in defined?
[Bug #21029]
Updated by S_H_ (Shun Hiraoka) 4 months ago
· Edited
Actions
#11
[ruby-core:122679]
I've fixed that defined? (x;) returns an expression when using parse.y.
https://github.com/ruby/ruby/pull/13821
However, I have a little skeptical about whether this change is a good idea. If any other good suggestions, I would appreciate it if you could comment.
Updated by kddnewton (Kevin Newton) 4 months ago
Actions
#12
[ruby-core:122680]
@S_H_ I agree, I think the overhead is not worth it in this case and we should pretend the ; do not exist on both cases.
Updated by S_H_ (Shun Hiraoka) 4 months ago
Actions
#13
[ruby-core:122741]
I agree that consistent behavior between both cases would be ideal.
Given the current structure of parse.y, wrapping with NODE_BLOCK seems like the most straightforward approach to make both defined?(;x) and defined?(x;) return "expression".
With my current changes, both forms now generate the same AST nodes, which I believe improves consistency across the board.
Also, I want to clarify my earlier comment about being "skeptical" — I was specifically referring to adding new parameters to the parser_params struct, not to the NODE_BLOCK wrapping approach itself. Sorry for any confusion caused.
Right now, the defined?(x;) test is failing on parse.y, which makes it hard to assess whether changes to universal_parser.c or other components are affecting the parse.y behavior. This adds friction when trying to work on parser-related modifications.
From a maintenance standpoint, I believe fixing this failing test would help ensure that future parse.y changes can be validated more reliably.
Would you be open to keeping this change in order to maintain test consistency?