You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An example of code which is rejected by MRI parser:
1.times do
puts(if true
break
end)
end
This code is accepted, though, despite having completely identical semantics:
1.times do
puts(if true
break
1
end)
end
I find this bit of static analysis in parse.y useless and obnoxious. However, not implementing it means that Parser will accept some invalid Ruby code (as what's valid and what is not is defined by parse.y behavior.)
I think it's fine to accept invalid code in these edge cases at the moment.
Most people will use parser to parse valid code anyway.
On Monday, June 17, 2013, Peter Zotov wrote:
An example of code which is rejected by MRI parser:
1.times do
puts(if true
break
end)
end
This code is accepted, though, despite having completely identical
semantics:
1.times do
puts(if true
break
1
end)
end
I find this bit of static analysis in parse.y useless and obnoxious.
However, not implementing it means that Parser will accept some invalid
Ruby code (as what's valid and what is not is defined by parse.y behavior.)
The problem is that we can't claim parsing Ruby unless the behavior is identical to parse.y's... this is also a huge problem for Rubinius, for example. They have to reimplement every single idiosyncratic hack which MRI has.
IMHO: It does not drive ruby forward to have only a single source of idiosyncratic hacks that get copied to all other implementations. @whitequark, so just claim "parser parses ruby that makes sense". There is no need to carry bugs around.
The problem with "parser parses ruby that makes sense" is that it's basically "parses ruby which @whitequark likes". I.e. not ruby but something else, perhaps a subset thereof.
Unfortunately, driving ruby forward must be done with MRI being the first, at least in the core language, or so it seems.
Oh and I claim to support earlier versions of ruby, so I'm not free even if they drop it in 3.0 or whatever version.
@whitequark I understand your concerns. Lets hope this gets dropped in 3.0. Or better 2.1. Isnt a subset of ruby enough? The subset that is actually in use. I don't think someone using such void value semantics is in production.
No alternative ruby implementation I know supports all MRI behavior, and this is a good thing. I'd opt to raise on such edge cases and fix them if someone can come up with a real world scenario where this behavior is needed?
@mbj All other Ruby implementations use MRI's parser, though.
I see your point. The problem is that "raising on edge cases" will pretty much resolve this issue, as this is what MRI's parser indeed does ;) And it's some strange and unspecified behavior.
@mbj Yes, like that, if by "should not" you mean "should not by common sense".
Yes; but writing such a linter is equivalent to just resolving this issue. Which I have no idea how to do, because this behavior is intricate and unspecified, and I just don't know a better way to write testcases than to throw various code at MRI and look how it reacts. (The part in parse.y which handles this is... erm... not very clear.)
@whitequark TBH I more and more feel: Ignore it till a real world bug report strikes in. Why port unspecified behavior from MRI? - This statement sounds lame from a be correct first POV. But the problem is to define correct here.
You can always warn in the README about this scenario.
@mbj Well, most of parse.y's behavior is unspecified (I think that the grammar in the ISO standard is not enough to replicate parse.y... may be very wrong though).
Yes, I think that warning in README is the way to go. Thanks!
If we want something like this to be linted I could fairly easily slap this in ruby-lint. Then again I think this use case is so rare that it might not be worth the extra effort.
It's something that won't trigger an error until you actually run it. When you run ruby with -c -W2 it will warn you about this, but I'm not sure how many people would have this hooked up to their editor.
Yep, the messages MRI produces are often not particularly helpful and more importantly - MRI's linting is not always consistent. That's some of the reasons that made us do linting ourselves in RuboCop.
@whitequark I'm not sure how that would be any different to analyse. In pseudo-ruby-lint code this would look something along the lines of the following:
classLolRubydefinitialize@buffer_node_types=false@node_types=[]enddefon_send(node)@buffer_node_types=trueenddefafter_send(node)@buffer_node_types=falseenddefafter_if(node)if@buffer_node_typesand@node_types == [:break]# add an error here...end@node_types.clearend# Currently ruby-lint doesn't have a catch-all callback method so I'd have to# implement that (which is trivial to do).defon_node(node)@node_types << node.typeif@buffer_nodesendend
Either way, I don't think this would belong in parser and as stated by others I'm fine with deviating from the Ruby "standard" here.
Activity
whitequark commentedon Jun 17, 2013
An example of code which is rejected by MRI parser:
This code is accepted, though, despite having completely identical semantics:
I find this bit of static analysis in parse.y useless and obnoxious. However, not implementing it means that Parser will accept some invalid Ruby code (as what's valid and what is not is defined by parse.y behavior.)
Your opinion? @mbj @yorickpeterse @judofyr @bbatsov
judofyr commentedon Jun 17, 2013
I think it's fine to accept invalid code in these edge cases at the moment.
Most people will use parser to parse valid code anyway.
On Monday, June 17, 2013, Peter Zotov wrote:
// Magnus Holm
bbatsov commentedon Jun 17, 2013
I agree with @whitequark that such analysis is pointless. I'm ok if Parser does not behave as MRI's parser in such scenarios.
lee-dohm commentedon Jun 17, 2013
👍 @bbatsov @judofyr I'd also count this as a low-priority thing to be fixed later, possibly much later.
mbj commentedon Jun 17, 2013
@whitequark I'd accept this edge case. IMHOs rubies definition of "valid" is just to unsharp here.
yorickpeterse commentedon Jun 17, 2013
I personally also agree that the statistical analysis is not required on parser level, I'd even argue that that would be wrong.
whitequark commentedon Jun 17, 2013
The problem is that we can't claim parsing Ruby unless the behavior is identical to parse.y's... this is also a huge problem for Rubinius, for example. They have to reimplement every single idiosyncratic hack which MRI has.
mbj commentedon Jun 18, 2013
IMHO: It does not drive ruby forward to have only a single source of idiosyncratic hacks that get copied to all other implementations. @whitequark, so just claim "parser parses ruby that makes sense". There is no need to carry bugs around.
whitequark commentedon Jun 18, 2013
The problem with "parser parses ruby that makes sense" is that it's basically "parses ruby which @whitequark likes". I.e. not ruby but something else, perhaps a subset thereof.
Unfortunately, driving ruby forward must be done with MRI being the first, at least in the core language, or so it seems.
Oh and I claim to support earlier versions of ruby, so I'm not free even if they drop it in 3.0 or whatever version.
whitequark commentedon Jun 18, 2013
That being said, I'm completely unexcited by the perspective of implementing and testing this.
mbj commentedon Jun 18, 2013
@whitequark I understand your concerns. Lets hope this gets dropped in 3.0. Or better 2.1. Isnt a subset of ruby enough? The subset that is actually in use. I don't think someone using such void value semantics is in production.
No alternative ruby implementation I know supports all MRI behavior, and this is a good thing. I'd opt to raise on such edge cases and fix them if someone can come up with a real world scenario where this behavior is needed?
whitequark commentedon Jun 18, 2013
@mbj All other Ruby implementations use MRI's parser, though.
I see your point. The problem is that "raising on edge cases" will pretty much resolve this issue, as this is what MRI's parser indeed does ;) And it's some strange and unspecified behavior.
mbj commentedon Jun 18, 2013
To be egoistic: I'm fine if parser parses the subset of ruby I'm use.
To understand the point: MRI raises where it should not?
Could we add dedicate linter that does the job?
whitequark commentedon Jun 18, 2013
@mbj Yes, like that, if by "should not" you mean "should not by common sense".
Yes; but writing such a linter is equivalent to just resolving this issue. Which I have no idea how to do, because this behavior is intricate and unspecified, and I just don't know a better way to write testcases than to throw various code at MRI and look how it reacts. (The part in parse.y which handles this is... erm... not very clear.)
mbj commentedon Jun 18, 2013
@whitequark TBH I more and more feel: Ignore it till a real world bug report strikes in. Why port unspecified behavior from MRI? - This statement sounds lame from a be correct first POV. But the problem is to define correct here.
You can always warn in the README about this scenario.
whitequark commentedon Jun 18, 2013
@mbj Well, most of parse.y's behavior is unspecified (I think that the grammar in the ISO standard is not enough to replicate parse.y... may be very wrong though).
Yes, I think that warning in README is the way to go. Thanks!
yorickpeterse commentedon Jun 18, 2013
If we want something like this to be linted I could fairly easily slap this in ruby-lint. Then again I think this use case is so rare that it might not be worth the extra effort.
whitequark commentedon Jun 18, 2013
@yorickpeterse It's not something you can meaningfully execute, so why lint against it?
yorickpeterse commentedon Jun 18, 2013
It's something that won't trigger an error until you actually run it. When you run ruby with
-c -W2it will warn you about this, but I'm not sure how many people would have this hooked up to their editor.yorickpeterse commentedon Jun 18, 2013
Also worth mentioning is that the errors Ruby in this case spits out aren't very user friendly:
bbatsov commentedon Jun 18, 2013
Yep, the messages MRI produces are often not particularly helpful and more importantly - MRI's linting is not always consistent. That's some of the reasons that made us do linting ourselves in RuboCop.
whitequark commentedon Jun 18, 2013
@yorickpeterse Um, no? Try this:
yorickpeterse commentedon Jun 18, 2013
@whitequark I'm not sure how that would be any different to analyse. In pseudo-ruby-lint code this would look something along the lines of the following:
Either way, I don't think this would belong in parser and as stated by others I'm fine with deviating from the Ruby "standard" here.
JoshCheek commentedon Jun 25, 2013
Here are a few more examples of void value expressions https://gist.github.com/JoshCheek/5625007