Syntax error I don't understand


#1

(I’m using Ruby 1.8.6.)

I’m trying to add a random number to an array. I do:

a = []
a << rand 3

But ruby replies with “syntax error, unexpected tINTEGER, expecting kDO
or ‘{’ or ‘(’”

Why’s that?

When I add parentheses to the function call, as in…

a = []
a << rand(3)

…then I don’t get this syntax error. I’d like to understand why this
happens.


#2

Albert S. wrote:

Why’s that?

When I add parentheses to the function call, as in…

a = []
a << rand(3)

…then I don’t get this syntax error. I’d like to understand why this
happens.

As I have learned, the parenthesis are optional for function arguments,
however there are some cases where that confuses the interpreter. It
would be my guess ruby is trying to do “a << rand” and then finds and
extra integer stuck on the end.

Putting the parenthesis around the integer forces ruby to perform the
“<<” on the whole function.

HTH

Matt


#3

Something I learned many years and several languages ago: “When in
doubt, use parentheses.” This avoids having to learn complicated rules
governing operator precedence etc, rules which can vary from one
language to another.

As a result my Ruby code probably has more () pairs than strictly
necessary. But I believe in letting the computer do the work rather than
busting my brain to reduce the source code by a few bytes.

As a compromise I sometimes strip out () pairs until the code fails the
unit tests, and then replace the last pair. :wink:

Dave


#4

Dave B. wrote:

“When in doubt, use parentheses.” This avoids having to learn
complicated rules

Matt H. wrote:

It would be my guess ruby is trying to do “a << rand” and then finds
an extra integer stuck on the end.

No doubt. But could anybody describe this special case more accurately
so I recognize it in the future? It even happens for “2 + rand 3”. I
don’t want to add parentheses in all my function calls, because I
understand that’s contrary to Ruby’s coding style.

I had a peek at a simplified BNF of ruby:

http://web.njit.edu/all_topics/Prog_Lang_Docs/html/ruby/yacc.html

and I see:

ARG : …
| ARG <<' ARG | ... | ARG+’ ARG
| ARG -' ARG | ARG*’ ARG
| ARG `/’ ARG
| …
| PRIMARY

PRIMARY : …
| FUNCTION
| …

FUNCTION : …
| OPERATION [(' [CALL_ARGS])’]
| …

COMMAND : …
| OPERATION CALL_ARGS
| …

And according to this, “a << rand 3” indeed is a syntax error because
“rand 3” isn’t a FUNCTION but a COMMAND. Since a COMMAND isn’t a
PRIMARY, it can’t stand for an ARG.

Nevetheless, I wonder if I should have known this without checking out
the BNF. Shouldn’t it be “common knowledge” that you can’t do “2 + rand
3” in Ruby?


#5

On 28.12.2008 13:08, Albert S. wrote:

Matt H. wrote:

It would be my guess ruby is trying to do “a << rand” and then finds
an extra integer stuck on the end.

No doubt. But could anybody describe this special case more accurately
so I recognize it in the future? It even happens for “2 + rand 3”. I
don’t want to add parentheses in all my function calls, because I
understand that’s contrary to Ruby’s coding style.

My approach is a different one - maybe you can use it, too: if I
encounter a syntax error, I try to see what’s wrong. Then I add
parentheses and if the syntax error goes away I leave it at that. I
don’t waste too much brain cycles on syntax - IMHO that’s wasted energy
unless you are designing a DSL. :slight_smile:

Cheers

robert


#6

Robert K. wrote:

[…]
I don’t waste too much brain cycles on syntax

  • IMHO that’s wasted energy

I’m not a strict fellow. I don’t mind putting extra parentheses.

I don’t mind the “2 + rand 3” issue in itself. The problem is that I’ve
just encountered yet another similar trivial issue[1], and it gives me a
bad impression of the language. It’s as if this compiler was sloppily
written. The reason I want to find the answers is to restore my faith in
this very beautiful language.

[1] http://www.ruby-forum.com/topic/174345


#7

On Dec 28, 2008, at 8:57 AM, Albert S. wrote:

I don’t mind the “2 + rand 3” issue in itself. The problem is that
I’ve
just encountered yet another similar trivial issue[1], and it gives
me a
bad impression of the language. It’s as if this compiler was sloppily
written. The reason I want to find the answers is to restore my
faith in
this very beautiful language.

compare

a = 99

1 + a 2

and

1 + rand 2

Clearly the first one is incorrect: you’d expect to see the message
“unexpected integer” (the 2, in this case). But syntactically, the
second statement is identical to the first.

In this case, it’s your job to disambiguate it by telling Ruby that 2
is a method parameter, and you do that by making it obvious that rand
is a method invocation—you put the parentheses.

Regards

Dave T.


#8

Dave T. wrote:

a = 99

1 + a 2
[…]
it’s your job to disambiguate it by telling Ruby that 2
is a method parameter, and you do that by […] parentheses.

Aha!

Dave, that makes much sense! I’m happy with that answer. Thanks.

Could you check out the other thread I opened[1] ? I’d be a bit
disappointed if this “to disambiguate variable from method” answer
applies there as well because we have to set a limit somewhere.

[1] http://www.ruby-forum.com/topic/174345


#9

Matt H. wrote:
g> Putting the parenthesis around the integer forces ruby to perform the

“<<” on the whole function.

Or around the subexpression:

a << (rand 3)

You could say that rand 3 is then treated as a separate phrase of
‘poetry mode’


#10

On Dec 28, 2008, at 5:58 AM, Dave B. wrote:

Something I learned many years and several languages ago: “When in
doubt, use parentheses.”

Yeah, I pretty much agree. Here are some good exceptions from myself
and other commenters though:

http://blog.grayproductions.net/articles/do_i_need_these_parentheses

James Edward G. II


#11

Albert S. removed_email_address@domain.invalid writes:

No doubt. But could anybody describe this special case more accurately
so I recognize it in the future? It even happens for “2 + rand 3”. I
don’t want to add parentheses in all my function calls, because I
understand that’s contrary to Ruby’s coding style.

I may use parentheses on function invocations more than most, but I
don’t think it’s contrary to “Ruby’s coding style”. Invocations
without parentheses can be nice for simpler statements and dsl-like
usage, but I personally prefer parentheses for invocations that aren’t
of the “function [argument, …]” form - such as the one you began the
thread with.

On a related note, using parentheses in expressions generally, as Dave
Bass mentioned, is not a bad practice.

When I was younger, I would pride myself in memorizing the operator
precedence of various languages, and use the minimum parentheses
necessary because I thought I was being “cool” or “smart”. I now feel
I was being neither, and it was of little benefit to others when
reading my code.