Syntax error: 1 + [0,1,2].index 1

1 + [0,1,2].index 1

SyntaxError: unexpected tINTEGER, expecting end-of-input

but this works

1 .+ [0,1,2].index 1

=> 2

why?

thanks and kind regards
--botp

Note that the below work too:

1 + [0, 1, 2].index(1)

=> 2

I think your first example is parsed like (1 + [0, 1, 2].index) 1. When you
use .+ then you don't use syntactic sugar for addition and call #+
explicitly. An expression of the form

object.method another_method argument

is parsed as

object.method(another_method(argument))

Solution? Always use parenthesis. I make an exception to this rule in some
places in Rails (for instance when defining a test I write test
'description' not test('description')).

Best regards

···

On Wed, Oct 14, 2015 at 7:20 AM, botp <botpena@gmail.com> wrote:

> 1 + [0,1,2].index 1
SyntaxError: unexpected tINTEGER, expecting end-of-input

but this works

> 1 .+ [0,1,2].index 1
=> 2

why?

thanks and kind regards
--botp

Hope this answers your query

>> 1 + [0,1,2].index 1
SyntaxError: (irb):1: syntax error, unexpected tINTEGER, expecting end-of-input
     from /home/ak/.rvm/rubies/ruby-2.2.2/bin/irb:11:in `<main>'
>> 1 + [0,1,2].index[1]
NoMethodError: undefined method `' for #<Enumerator: [0, 1, 2]:index>
     from (irb):2
     from /home/ak/.rvm/rubies/ruby-2.2.2/bin/irb:11:in `<main>'
>> 1 + [0,1,2][1]
=> 2

···

-------

http://kardrak.com/1/Karthikeyan%20A%20K

On Wednesday 14 October 2015 10:50 AM, botp wrote:

1 + [0,1,2].index 1

SyntaxError: unexpected tINTEGER, expecting end-of-input

but this works

1 .+ [0,1,2].index 1

=> 2

why?

thanks and kind regards
--botp

Hope this answers your query
1 + [0,1,2][1]
=> 2

hi AK,

just to help you help me,

[2,0,1].index 1

=> 2

[2,0,1][1]

=> 0

just want to know why the syntax fails.

thanks and kind regards
--botp

···

On Wed, Oct 14, 2015 at 1:28 PM, Karthikeyan A K <karthikeyan@openmailbox.org> wrote:

I think your first example is parsed like (1 + [0, 1, 2].index) 1. When you
use .+ then you don't use syntactic sugar for addition and call #+
explicitly. An expression of the form

indeed that was what i thought. the + is just syntactic sugar of .+
the parser should just then parse it as 1 .+ rhs
where rhs = "[0, 1, 2].index) 1"

Solution? Always use parenthesis.

am sorry. we diverge. am not a fan of parens in ruby. i only use
parens on needed basis. here in this case, i felt it should Not be
needed.

thanks and kind regards
--botp

···

On Wed, Oct 14, 2015 at 1:30 PM, Greg Navis <contact@gregnavis.com> wrote:

Consider the expression a = b.fetch c + d.foo e + f. Is that supposed to be
b.fetch(c) + d.foo(e) + f, or b.fetch(c + d.foo(e + f)), or b.fetch(c) +
d.foo(e + f), or b.fetch(c + d.foo(e)) + f? How is anyone reading your code
supposed to know? How is the interpreter?

a + b in ruby is syntactic sugar for a.+(b). I guess then what the ruby
interpreter does when it encounters a + symbol is to pull the next
expression off the current or next line and evaluates that as the #+ method
parameter. You seem to be suggesting that it should evaluate to the end of
the line maybe? In that case you'll need special handling for 'if' or a =
b + c if d will evaluate to a = b.+(c if d). Maybe another way to do it
would be to go back and re-evaluate if an unexpected keyword is
encountered, but you can imagine that's going to add some complexity to the
interpreter.

More importantly though, it adds more complexity for anyone wanting to read
ruby code, because they have to internalize these rules to understand how
their code will be evaluated. Current ruby behaviour may be "dumb" but once
you know it, it's easy to remember.

I like how ruby lets me drop parenthesis, sometimes they are unnecessary
clutter. A good rule of thumb I keep to though is that it is a Nice Thing
To Do to always use parentheses instead of relying on operator precedence.
Some people use several different languages on a daily basis, any of which
may have subtly different precedence rules, and your code will be that much
more pleasant for those people to work with if they don't have to learn
ruby's.

Cheers,
Doug Hammond

···

On Wed, 14 Oct 2015 at 08:07 botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 1:30 PM, Greg Navis <contact@gregnavis.com> wrote:
> I think your first example is parsed like (1 + [0, 1, 2].index) 1. When
you
> use .+ then you don't use syntactic sugar for addition and call #+
> explicitly. An expression of the form

indeed that was what i thought. the + is just syntactic sugar of .+
the parser should just then parse it as 1 .+ rhs
where rhs = "[0, 1, 2].index) 1"

> Solution? Always use parenthesis.

am sorry. we diverge. am not a fan of parens in ruby. i only use
parens on needed basis. here in this case, i felt it should Not be
needed.

thanks and kind regards
--botp

I agree: not have to use parentheses is one major factor which makes Ruby
so elegant. I often also only use them when they are needed or I want to
make function / method calls obvious.

Kind regards

robert

···

On Wed, Oct 14, 2015 at 8:07 AM, botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 1:30 PM, Greg Navis <contact@gregnavis.com> wrote:

> Solution? Always use parenthesis.

am sorry. we diverge. am not a fan of parens in ruby. i only use
parens on needed basis. here in this case, i felt it should Not be
needed.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can -
without end}
http://blog.rubybestpractices.com/

Consider the expression a = b.fetch c + d.foo e + f. Is that supposed to be

<snip>..

hi doug, thanks. but would you know why ruby does not fail on this dot
expression?

1 .+ [0, 2,1].index 1 if 1==1

=> 3

kind regards
--botp

···

On Wed, Oct 14, 2015 at 4:14 PM, Doug Lake-Hammond <d.lakehammond@gmail.com> wrote:

Basically '.+' seems to move the interpreter to a different mode where it
assumes whitespace-separated tokens are arguments of the method token to
the left, such as 'puts get_thing a, b'. Even here there are limitations on
what you can get away with; the interpreter will very deliberately refuse
to guess what 'foo 1, bar 2, 3' is supposed to mean.

There are also operator precedence rules to be aware of here. The 'if'
keyword is a binary operator, on the same level as 'or'/'and', in fact it's
basically just 'and' with the operand evaluation order reversed. Note the
difference in evaluation order from '||'/'&&':

2.2.3 :001 > 1 .+ [0,2,1].index 1 if 1==1
=> 3
2.2.3 :002 > 1 .+ [0,2,1].index 1 and 1==1
=> true
2.2.3 :003 > 1 .+ [0,2,1].index 1 && 1==1
TypeError: nil can't be coerced into Fixnum
from (irb):3:in `+'
from (irb):3

You might get a more thorough answer regarding interpreter rules on
ruby-lang if you ask nicely enough :slight_smile:

Cheers,
Doug

···

On Wed, 14 Oct 2015 at 16:30 botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 4:14 PM, Doug Lake-Hammond > <d.lakehammond@gmail.com> wrote:
> Consider the expression a = b.fetch c + d.foo e + f. Is that supposed to
be
<snip>..

hi doug, thanks. but would you know why ruby does not fail on this dot
expression?

> 1 .+ [0, 2,1].index 1 if 1==1
=> 3

kind regards
--botp

Or it might be better to say that '+' without '.' moves the interpreter to
a different mode, where '.+' is the more general default behaviour.

···

On Wed, 14 Oct 2015 at 16:49 Doug Lake-Hammond <d.lakehammond@gmail.com> wrote:

Basically '.+' seems to move the interpreter to a different mode where it
assumes whitespace-separated tokens are arguments of the method token to
the left, such as 'puts get_thing a, b'. Even here there are limitations on
what you can get away with; the interpreter will very deliberately refuse
to guess what 'foo 1, bar 2, 3' is supposed to mean.

There are also operator precedence rules to be aware of here. The 'if'
keyword is a binary operator, on the same level as 'or'/'and', in fact it's
basically just 'and' with the operand evaluation order reversed. Note the
difference in evaluation order from '||'/'&&':

2.2.3 :001 > 1 .+ [0,2,1].index 1 if 1==1
=> 3
2.2.3 :002 > 1 .+ [0,2,1].index 1 and 1==1
=> true
2.2.3 :003 > 1 .+ [0,2,1].index 1 && 1==1
TypeError: nil can't be coerced into Fixnum
from (irb):3:in `+'
from (irb):3

You might get a more thorough answer regarding interpreter rules on
ruby-lang if you ask nicely enough :slight_smile:

Cheers,
Doug

On Wed, 14 Oct 2015 at 16:30 botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 4:14 PM, Doug Lake-Hammond >> <d.lakehammond@gmail.com> wrote:
> Consider the expression a = b.fetch c + d.foo e + f. Is that supposed
to be
<snip>..

hi doug, thanks. but would you know why ruby does not fail on this dot
expression?

> 1 .+ [0, 2,1].index 1 if 1==1
=> 3

kind regards
--botp

The kinds of questions you're asking are esoterica that are only "understood" by studying the actual parser code of ruby... as a pained "expert" in this area, I'd beg of you not to bother going down this road.

The short answer is: because that is the way it is defined.

If you think you found an edge-case that you think is in error, you're welcome to file a bug at bugs.ruby-lang.org and see if matz agrees. In this case... *shrug* I dunno. Maybe, maybe not.

···

On Oct 14, 2015, at 07:30, botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 4:14 PM, Doug Lake-Hammond > <d.lakehammond@gmail.com> wrote:

Consider the expression a = b.fetch c + d.foo e + f. Is that supposed to be

<snip>..

hi doug, thanks. but would you know why ruby does not fail on this dot
expression?

1 .+ [0, 2,1].index 1 if 1==1

=> 3

'+' is an operator and '.+' is a function/method call; they have different
parsing rules and precedence. In this case the operator parsing may
actually be buggy. Someone very knowledgable about the parser (like nobu,
or Tom Enebo) might be able to tell us more.

···

On 15/10/2015 12:51 AM, "Doug Lake-Hammond" <d.lakehammond@gmail.com> wrote:

Or it might be better to say that '+' without '.' moves the interpreter to
a different mode, where '.+' is the more general default behaviour.

On Wed, 14 Oct 2015 at 16:49 Doug Lake-Hammond <d.lakehammond@gmail.com> > wrote:

Basically '.+' seems to move the interpreter to a different mode where it
assumes whitespace-separated tokens are arguments of the method token to
the left, such as 'puts get_thing a, b'. Even here there are limitations on
what you can get away with; the interpreter will very deliberately refuse
to guess what 'foo 1, bar 2, 3' is supposed to mean.

There are also operator precedence rules to be aware of here. The 'if'
keyword is a binary operator, on the same level as 'or'/'and', in fact it's
basically just 'and' with the operand evaluation order reversed. Note the
difference in evaluation order from '||'/'&&':

2.2.3 :001 > 1 .+ [0,2,1].index 1 if 1==1
=> 3
2.2.3 :002 > 1 .+ [0,2,1].index 1 and 1==1
=> true
2.2.3 :003 > 1 .+ [0,2,1].index 1 && 1==1
TypeError: nil can't be coerced into Fixnum
from (irb):3:in `+'
from (irb):3

You might get a more thorough answer regarding interpreter rules on
ruby-lang if you ask nicely enough :slight_smile:

Cheers,
Doug

On Wed, 14 Oct 2015 at 16:30 botp <botpena@gmail.com> wrote:

On Wed, Oct 14, 2015 at 4:14 PM, Doug Lake-Hammond >>> <d.lakehammond@gmail.com> wrote:
> Consider the expression a = b.fetch c + d.foo e + f. Is that supposed
to be
<snip>..

hi doug, thanks. but would you know why ruby does not fail on this dot
expression?

> 1 .+ [0, 2,1].index 1 if 1==1
=> 3

kind regards
--botp