Forum: Ruby Syntax error I don't understand

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2008-12-28 11:28
(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.
8fa0f5c2bf8ad238baa4e20cb0360ebd?d=identicon&s=25 Matt Harrison (iwasinnamuknow)
on 2008-12-28 12:22
(Received via mailing list)
Albert Schlef 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
9d751d4cd704a4efe3a335c77c4487a3?d=identicon&s=25 Dave Bass (dogsbody)
on 2008-12-28 12:58
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. ;-)

Dave
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2008-12-28 13:09
Dave Bass wrote:
>
> "When in doubt, use parentheses." This avoids having to learn
> complicated rules

Matt Harrison 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...

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?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-12-28 14:05
(Received via mailing list)
On 28.12.2008 13:08, Albert Schlef wrote:
> Matt Harrison 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. :-)

Cheers

  robert
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2008-12-28 15:57
Robert Klemme 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
5d06917e13b29bcff1c1609492c06873?d=identicon&s=25 Dave Thomas (Guest)
on 2008-12-28 17:31
(Received via mailing list)
On Dec 28, 2008, at 8:57 AM, Albert Schlef 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 Thomas
699c00ad35f2755810b4aa5f423d73e2?d=identicon&s=25 Albert Schlef (alby)
on 2008-12-28 18:22
Dave Thomas 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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2008-12-28 18:24
(Received via mailing list)
On Dec 28, 2008, at 5:58 AM, Dave Bass 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...

James Edward Gray II
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-12-28 20:06
Matt Harrison 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'
8666d1ebabcea440585dfe831a4af9f1?d=identicon&s=25 Brian Adkins (Guest)
on 2008-12-29 20:35
(Received via mailing list)
Albert Schlef <albertschlef@gmail.com> 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.
This topic is locked and can not be replied to.