[BUG] Bug in ruby parser

Hello,

I think I found a bug in how ruby parses code, or at least an unexpected
result. If I enter:
2 /(1 * (1 / 1))

The result is 2. But if I enter:
2.to_f /(1 * (1 / 1))

It returns:
SyntaxError: (irb):1: end pattern with unmatched parenthesis

This is because it is parsing part of it as a regular expression. The
weird thing is that it only does so when using 2.to_f but not when using 2.

Regards,

···

--
Roberto Romero

1. If you believe you've found a bug in Ruby, it is worth trying to report
it at https://bugs.ruby-lang.org/ (it is not scary! an if it is not a bug,
people there are pretty friendly and will explain)
2. Ruby parser is pretty forgiving (it allows a lot of optional elements),
and therefore it is pretty hard to design it. In your example:

2 / .... is unambiguous (/ after number can only mean operator)
2.to_f /... is ambiguous (it may mean "2.to_f <division operator>
something", or "2.to_f(/regexp....)"

Ruby decides on this ambiguity by spaces: without space after / you
probably meant regexp, with space you probably meant division:

2.to_f / (1 * (1 / 1))
=> 2.0

So you may still want to report it, but expect to be said it is not a bug,
just how things are.

···

2018-03-15 13:20 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

Hello,

I think I found a bug in how ruby parses code, or at least an unexpected
result. If I enter:
2 /(1 * (1 / 1))

The result is 2. But if I enter:
2.to_f /(1 * (1 / 1))

It returns:
SyntaxError: (irb):1: end pattern with unmatched parenthesis

This is because it is parsing part of it as a regular expression. The
weird thing is that it only does so when using 2.to_f but not when using 2.

Regards,
--
Roberto Romero

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Yes its happening.

Its working for:

(2.to_f) /(1 * (1 / 1))
=> 2.0
2.0 /(1 * (1 / 1))
=> 2.0
but,
2.to_f /(1 * (1 / 1))
SyntaxError ((irb):5: end pattern with unmatched parenthesis: /(1 * (1 /
(irb):5: syntax error, unexpected tINTEGER, expecting end-of-input
2.to_f /(1 * (1 / 1))
                  ^)

Thanks
Raj Kumar

···

On Thu, Mar 15, 2018 at 4:50 PM, Roberto Romero <sildurin@gmail.com> wrote:

Hello,

I think I found a bug in how ruby parses code, or at least an unexpected
result. If I enter:
2 /(1 * (1 / 1))

The result is 2. But if I enter:
2.to_f /(1 * (1 / 1))

It returns:
SyntaxError: (irb):1: end pattern with unmatched parenthesis

This is because it is parsing part of it as a regular expression. The
weird thing is that it only does so when using 2.to_f but not when using 2.

Regards,
--
Roberto Romero

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that can be interpreted as regex. Including the explicit empty argument bypasses the attempt to interpret what follows to_f as a parameter.

···

On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> wrote:

Hello,

I think I found a bug in how ruby parses code, or at least an unexpected
result. If I enter:
2 /(1 * (1 / 1))

The result is 2. But if I enter:
2.to_f /(1 * (1 / 1))

It returns:
SyntaxError: (irb):1: end pattern with unmatched parenthesis

This is because it is parsing part of it as a regular expression. The
weird thing is that it only does so when using 2.to_f but not when using 2.

Regards,
--
Roberto Romero

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

My guess, sans research, is that to_f takes an optional parameter that

can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems), not
later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

···

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that can
be interpreted as regex. Including the explicit empty argument bypasses
the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when using
2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=
>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

···

--
Roberto Romero

El 15 mar. 2018 12:37, "Victor Shepelev" <zverok.offline@gmail.com> escribió:

My guess, sans research, is that to_f takes an optional parameter that

can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems), not
later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that can
be interpreted as regex. Including the explicit empty argument bypasses
the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when using
2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

What ruby could do is try the other meaning (method + operator) before

throwing a syntax error.

Designing parsers is REALLY hard. It is not like a chain of "if-elses",
where you can just throw one or two more if-s anytime.

And there is no practical reason to optimize parser for what is just a bad
code. Adding one space (which also increases readability) solves the
problem, so...

···

2018-03-15 14:19 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

--
Roberto Romero

El 15 mar. 2018 12:37, "Victor Shepelev" <zverok.offline@gmail.com> > escribió:

> My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems), not
later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex. Including the explicit empty argument
bypasses the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when
using 2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

It is syntactically correct code.

No, it is not.
All you can say is "I expected this to be syntactically correct".

Ruby's grammar is defined the way that prohibits this grammar, treating /
as a start of Regexp

All Ruby parsers in existence (MRI, JRuby,
https://github.com/whitequark/parser\) consistently fail to parse this with
the same explanation.

Ruby grammar *is* space-dependent in ambiguous cases, and it is designed
this way, that's not a bug nobody seen and you've suddenly found.

Try also this:
p +1
# => prints 1
p + 1
# => NoMethodError: undefined method `+' for nil:NilClass

···

2018-03-15 15:14 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

--
Roberto Romero

El 15 mar. 2018 13:45, "Victor Shepelev" <zverok.offline@gmail.com> > escribió:

> What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

Designing parsers is REALLY hard. It is not like a chain of "if-elses",
where you can just throw one or two more if-s anytime.

Yes, it is quite hard to do it right.

And there is no practical reason to optimize parser for what is just a bad
code. Adding one space (which also increases readability) solves the
problem, so...

It is syntactically correct code. Ruby should not behave differently
depending on coding style.

2018-03-15 14:19 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

--
Roberto Romero

El 15 mar. 2018 12:37, "Victor Shepelev" <zverok.offline@gmail.com> >> escribió:

> My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems), not
later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex. Including the explicit empty argument
bypasses the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> >>> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an
unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when
using 2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

It is syntactically correct code.

No, it is not.
All you can say is "I expected this to be syntactically correct".

Ruby's grammar is defined the way that prohibits this grammar, treating /
as a start of Regexp

It doesn't treat / as a start of Regexp when I use 2.to_f(). That is
inconsistent.

All Ruby parsers in existence (MRI, JRuby, https://github.com/
whitequark/parser) consistently fail to parse this with the same
explanation.

Ruby grammar *is* space-dependent in ambiguous cases, and it is designed
this way, that's not a bug nobody seen and you've suddenly found.

So behaving differently depending if I use 2 or 2.to_f or 2.to_f() even if
all of them are the same is not a bug?

Try also this:
p +1
# => prints 1
p + 1
# => NoMethodError: undefined method `+' for nil:NilClass

···

El 15 mar. 2018 14:26, "Victor Shepelev" <zverok.offline@gmail.com> escribió:

2018-03-15 15:14 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

--
Roberto Romero

El 15 mar. 2018 13:45, "Victor Shepelev" <zverok.offline@gmail.com> > escribió:

> What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

Designing parsers is REALLY hard. It is not like a chain of "if-elses",
where you can just throw one or two more if-s anytime.

Yes, it is quite hard to do it right.

And there is no practical reason to optimize parser for what is just a bad
code. Adding one space (which also increases readability) solves the
problem, so...

It is syntactically correct code. Ruby should not behave differently
depending on coding style.

2018-03-15 14:19 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

--
Roberto Romero

El 15 mar. 2018 12:37, "Victor Shepelev" <zverok.offline@gmail.com> >> escribió:

> My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems), not
later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex. Including the explicit empty argument
bypasses the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> >>> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an
unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when
using 2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

It doesn't treat / as a start of Regexp when I use 2.to_f(). That is

inconsistent.

Try this:
2.to_f +1
2.to_f + 1
2.to_f() +1

This is not "inconsistent", but a conscious tradeoff of "forgiving" grammar
(e.g. one where you can use or omit parens, use or omit spaces and so on).
However smart parser is, sometimes you need just stop trying to solve all
the weird cases and go with the most reasonable guess.

And no, change in parsing because of parens is NOT inconsistency, it is a
feature allowing go with simplest possible code in simple cases and use
parens to clarify meaning in more complicated ones.

For example, this is also "inconsistent" speaking in your words:
p (1..3).map { |i| i.to_s }
# => ["1", "2", "3"]
p (1..3).map do |i| i.to_s end
# => #<Enumerator: 1..3:map>
p((1..3).map do |i| i.to_s end)
# => ["1", "2", "3"]

That's just how things are here.

And anyway, I don't understand what you are trying to prove.

Is it "Ruby is bad for having this not working"? -- then go to
https://bugs.ruby-lang.org/ and write it there. And prepare to discuss your
position and prove it should work another way around.

Or is it just "You, Victor, is wrong, stop saying it is not a bug"? -- OK,
I am giving up. Who am I to try explaining to people who don't want any
explanations?..

···

2018-03-15 15:39 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

El 15 mar. 2018 14:26, "Victor Shepelev" <zverok.offline@gmail.com> > escribió:

> It is syntactically correct code.

No, it is not.
All you can say is "I expected this to be syntactically correct".

Ruby's grammar is defined the way that prohibits this grammar, treating /
as a start of Regexp

It doesn't treat / as a start of Regexp when I use 2.to_f(). That is
inconsistent.

All Ruby parsers in existence (MRI, JRuby, whit (Vítek Pliska) · GitHub
equark/parser) consistently fail to parse this with the same explanation.

Ruby grammar *is* space-dependent in ambiguous cases, and it is designed
this way, that's not a bug nobody seen and you've suddenly found.

So behaving differently depending if I use 2 or 2.to_f or 2.to_f() even
if all of them are the same is not a bug?

Try also this:
p +1
# => prints 1
p + 1
# => NoMethodError: undefined method `+' for nil:NilClass

2018-03-15 15:14 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

--
Roberto Romero

El 15 mar. 2018 13:45, "Victor Shepelev" <zverok.offline@gmail.com> >> escribió:

> What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

Designing parsers is REALLY hard. It is not like a chain of "if-elses",
where you can just throw one or two more if-s anytime.

Yes, it is quite hard to do it right.

And there is no practical reason to optimize parser for what is just a
bad code. Adding one space (which also increases readability) solves the
problem, so...

It is syntactically correct code. Ruby should not behave differently
depending on coding style.

2018-03-15 14:19 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

What ruby could do is try the other meaning (method + operator) before
throwing a syntax error.

--
Roberto Romero

El 15 mar. 2018 12:37, "Victor Shepelev" <zverok.offline@gmail.com> >>> escribió:

> My guess, sans research, is that to_f takes an optional parameter
that can be interpreted as regex.

No, it does not have any arguments, but the problem is at *parsing* stage
(when Ruby doesn't know what the method is, and what arguments it
could take): it is just two completely different options how to parse it
(method + regex or result of method + operator), and parser needs to take
one of them *at this point* (to understand how to read next lexems),
not later when it already knows "Oh, it is to_f, it doesn't have any
arguments... So, probably, it wasn't a regexp!"

2018-03-15 13:31 GMT+02:00 Bill Felton <subscriptions@cagttraining.com>:

It works if you use 2.to_f(). (At least in 2.5)
My guess, sans research, is that to_f takes an optional parameter that
can be interpreted as regex. Including the explicit empty argument
bypasses the attempt to interpret what follows to_f as a parameter.

> On Mar 15, 2018, at 7:20 AM, Roberto Romero <sildurin@gmail.com> >>>> wrote:
>
> Hello,
>
> I think I found a bug in how ruby parses code, or at least an
unexpected
> result. If I enter:
> 2 /(1 * (1 / 1))
>
> The result is 2. But if I enter:
> 2.to_f /(1 * (1 / 1))
>
> It returns:
> SyntaxError: (irb):1: end pattern with unmatched parenthesis
>
> This is because it is parsing part of it as a regular expression. The
> weird thing is that it only does so when using 2.to_f but not when
using 2.
>
> Regards,
> --
> Roberto Romero
>
> Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org
?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

It doesn't treat / as a start of Regexp when I use 2.to_f(). That is inconsistent.

My 10p worth: I would expect `/(blahblahblah` to be the start of a Regexp. But I would expect `/ (blahblahblah` (space after the slash) to be part of a math expression.

And that’s just how Ruby parses it, too:

[1] pry(main)> 2.to_f /(1 * (1 / 1))
SyntaxError: unexpected tINTEGER, expecting end-of-input
2.to_f /(1 * (1 / 1))
                   ^
[1] pry(main)> 2.to_f / (1 * (1 / 1))
=> 2.0
If you surround math operators with spaces, it all works fine. I think most people do that?

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

> It doesn't treat / as a start of Regexp when I use 2.to_f(). That is
inconsistent.

Try this:
2.to_f +1
2.to_f + 1
2.to_f() +1

This is not "inconsistent", but a conscious tradeoff of "forgiving"
grammar (e.g. one where you can use or omit parens, use or omit spaces
and so on). However smart parser is, sometimes you need just stop
trying to solve all the weird cases and go with the most reasonable
guess.

And no, change in parsing because of parens is NOT inconsistency, it
is a feature allowing go with simplest possible code in simple cases
and use parens to clarify meaning in more complicated ones.

For example, this is also "inconsistent" speaking in your words:
p (1..3).map { |i| i.to_s }
# => ["1", "2", "3"]
p (1..3).map do |i| i.to_s end
# => #<Enumerator: 1..3:map>
p((1..3).map do |i| i.to_s end)
# => ["1", "2", "3"]

That's just how things are here.

And anyway, I don't understand what you are trying to prove.

Is it "Ruby is bad for having this not working"? -- then go
to https://bugs.ruby-lang.org/ and write it there. And prepare to
discuss your position and prove it should work another way around.

It is this case.

Or is it just "You, Victor, is wrong, stop saying it is not a bug"? --
OK, I am giving up. Who am I to try explaining to people who don't
want any explanations?..

But also it is "You, Victor, stop saying ruby fails because omitting a
space is bad code. It is not bad code." If ruby decides /(1.to_f * (100
/ 100)) is a malformed regexp, I think it should do decide it always, no
matter what's on the left of that, being 2, 2.to_f or var_name. It is
confusing. Anyways, yes, this may not be the place to discuss that.

Just out of curiosity, is this also how things are here?:
puts defined?(hello).class;if false;hello=1;end;puts defined?(hello).class

···

El 03/15/2018 a las 02:52 PM, Victor Shepelev escribió:

--

Roberto Romero

Is it "Ruby is bad for having this not working"? -- then go to

https://bugs.ruby-lang.org/ and write it there. And prepare to discuss your
position and prove it should work another way around.

It is this case.

Then you know what to do, OK?

Or is it just "You, Victor, is wrong, stop saying it is not a bug"? --

OK, I am giving up. Who am I to try explaining to people who don't want any
explanations?..

But also it is "You, Victor, stop saying ruby fails because omitting a

space is bad code. It is not bad code."

In fact, it is. It is clearly defined by Ruby grammar and consistently
implemented in all versions and variants of Ruby.

If ruby decides /(1.to_f * (100 / 100)) is a malformed regexp, I think it

should do decide it always, no matter what's on the left of that, being 2,
2.to_f or var_name. It is confusing. Anyways, yes, this may not be the
place to discuss that.

You think this, then try to persuade Ruby core team, not me, that they
should complicate parser even more for this, definitely very important,
frequent and critical case.

Just out of curiosity, is this also how things are here?:
puts defined?(hello).class;if false;hello=1;end;puts defined?(hello).class

Yes. It is called variable scoping.
if-expression, by definition, does not create a separate scope, so every
local variable defined inside expression, even in the unreachable branch,
becomes defined.

···

2018-03-15 16:34 GMT+02:00 Roberto Romero <sildurin@gmail.com>:

El 03/15/2018 a las 02:52 PM, Victor Shepelev escribió:

> It doesn't treat / as a start of Regexp when I use 2.to_f(). That is
inconsistent.

Try this:
2.to_f +1
2.to_f + 1
2.to_f() +1

This is not "inconsistent", but a conscious tradeoff of "forgiving"
grammar (e.g. one where you can use or omit parens, use or omit spaces and
so on). However smart parser is, sometimes you need just stop trying to
solve all the weird cases and go with the most reasonable guess.

And no, change in parsing because of parens is NOT inconsistency, it is a
feature allowing go with simplest possible code in simple cases and use
parens to clarify meaning in more complicated ones.

For example, this is also "inconsistent" speaking in your words:
p (1..3).map { |i| i.to_s }
# => ["1", "2", "3"]
p (1..3).map do |i| i.to_s end
# => #<Enumerator: 1..3:map>
p((1..3).map do |i| i.to_s end)
# => ["1", "2", "3"]

That's just how things are here.

And anyway, I don't understand what you are trying to prove.

Is it "Ruby is bad for having this not working"? -- then go to
https://bugs.ruby-lang.org/ and write it there. And prepare to discuss
your position and prove it should work another way around.

It is this case.

Or is it just "You, Victor, is wrong, stop saying it is not a bug"? --
OK, I am giving up. Who am I to try explaining to people who don't want any
explanations?..

But also it is "You, Victor, stop saying ruby fails because omitting a
space is bad code. It is not bad code." If ruby decides /(1.to_f * (100 /
100)) is a malformed regexp, I think it should do decide it always, no
matter what's on the left of that, being 2, 2.to_f or var_name. It is
confusing. Anyways, yes, this may not be the place to discuss that.

Just out of curiosity, is this also how things are here?:
puts defined?(hello).class;if false;hello=1;end;puts defined?(hello).class

--

Roberto Romero

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Sarcasm is not going to convince anyone.

···

El 03/15/2018 a las 04:19 PM, Victor Shepelev escribió:

> If ruby decides /(1.to_f * (100 / 100)) is a malformed regexp, I
think it should do decide it always, no matter what's on the left of
that, being 2, 2.to_f or var_name. It is confusing. Anyways, yes, this
may not be the place to discuss that.

You think this, then try to persuade Ruby core team, not me, that they
should complicate parser even more for this, definitely very
important, frequent and critical case.

--
Roberto Romero

My chime in here is that ruby congruence is one of it's most well
established virtues. I should like to think maintainers will continue to
take it as seriously as Matsumoto did in his initial works. It is what I
have long been telling people about, and it deserves maintenance of this
legacy, even in minutia. The whole idea is that things that seem like they
should work, should work, and in as intuitive way as possible. In the
short run there will always be exceptions, but in the long run, that is
what ruby maintainers inherit, and I think should take responsibility for.

···

On Thu, Mar 15, 2018 at 8:34 AM, Roberto Romero <sildurin@gmail.com> wrote:

El 03/15/2018 a las 04:19 PM, Victor Shepelev escribió:

> > If ruby decides /(1.to_f * (100 / 100)) is a malformed regexp, I
> think it should do decide it always, no matter what's on the left of
> that, being 2, 2.to_f or var_name. It is confusing. Anyways, yes, this
> may not be the place to discuss that.
>
> You think this, then try to persuade Ruby core team, not me, that they
> should complicate parser even more for this, definitely very
> important, frequent and critical case.

Sarcasm is not going to convince anyone.

--
Roberto Romero

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Please understand that your 3 examples are all VERY different items

2 is an object
2.to_f() is a unambigious call of the to_f method of the 2 object with an
implicit declaration of no arguments
2.to_f is a very much ambigious call to the to_f method of the 2 object
with at least a couple of parsing/engine evaluation variants based on what
comes next

1) If there is no potential argument to the right then it is treated as a
short hand for to_f() - either a line ending or bracketing the method call
- i.e. (2.to_f) allows the engine to treat it as such
2) If there is something that is a possible argument to the right - it is
treated as an argument - therefore when you go with 2.to_f / 1 you have the
engine looking at the / character as the beginning of a regex and therefore
you get errors regarding invalid regexes.
3) If there is soemthing to the right that cannot be an argument - i.e
2.to_f * 2 - then the engine treats the 2.to_f as it does with #1 and you
can use the shortcut here.
4) You immediately chain another implicit method call to the expression -
i.e. 2.to_f./1 - then the engine understands that the / is a method call
and therefore allows for the shorthand call to both to_f and /
5) You have a weirder edge case in that 2.to_f/1 works - and that is
because - going back ot the rules of the shorthand of the 2.to_f method
call - the lack of a space between the to_f and / informs the engine that
you are chaining method calls as opposed to passing an argument. This also
only works because of the use of a mathematical operation as opposed to a
"word" method call (i.e. 2.to_fputs) because the engine treats mathematical
operators slightly different in this particular edge case.

There is simply no other way for the system to work properly. The only
possible change would be to make all calls unambigious to the parser and
require () after any call that has no arguments - but that would be a major
change for a scenario which has a very declarative error and is extremely
simple to solve. If you choose to use shorthand for method calls - i.e. not
using () for no arguments - then you need to appreciate that shorthand
calls sometimes have edge cases - you have hit an edge case in your desired
use case.

It's not perfect - but it is what we have - and I can't imagine a change
forthcoming for your edge case here.

John

···

On Thu, Mar 15, 2018 at 6:39 AM, Roberto Romero <sildurin@gmail.com> wrote:

El 15 mar. 2018 14:26, "Victor Shepelev" <zverok.offline@gmail.com> > escribió:

> It is syntactically correct code.

No, it is not.
All you can say is "I expected this to be syntactically correct".

Ruby's grammar is defined the way that prohibits this grammar, treating /
as a start of Regexp

It doesn't treat / as a start of Regexp when I use 2.to_f(). That is
inconsistent.

All Ruby parsers in existence (MRI, JRuby, whit (Vítek Pliska) · GitHub
equark/parser) consistently fail to parse this with the same explanation.

Ruby grammar *is* space-dependent in ambiguous cases, and it is designed
this way, that's not a bug nobody seen and you've suddenly found.

So behaving differently depending if I use 2 or 2.to_f or 2.to_f() even
if all of them are the same is not a bug?