Why can't I use "or" here?

(The problem is in both Ruby 1.8 and Ruby 1.9)

The expression:

  puts(nil || 4)

works as expected. It prints '4'.

But this expression:

  puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

···

--
Posted via http://www.ruby-forum.com/.

Hm, on Ruby 1.9.1 I get:
irb(main):001:0> puts nil or 4

=> 4
irb(main):002:0> puts(nil or 4)
SyntaxError: (irb):2: syntax error, unexpected keyword_or, expecting ')'
puts(nil or 4)
            ^
         from C:/Ruby19/bin/irb:12:in `<main>'
irb(main):003:0> puts(nil || 4)
4
=> nil

This seems like a bug to me, since parenthesis *should* "only" make method calls and precedent unambigious.

···

On 31.12.2009 03:24, Albert Schlef wrote:

(The problem is in both Ruby 1.8 and Ruby 1.9)

The expression:

   puts(nil || 4)

works as expected. It prints '4'.

But this expression:

   puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

--
Phillip Gawlowski

Albert Schlef wrote:

[...]
  puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

Looks like a genuine bug to me. I can verify that behavior in MRI,
YARV, JRuby, IronRuby and Rubinius (which is not terribly surprising
since they all use the exact same parser).

I'd be interested in XRuby, since that's the only sort-of complete
(well, for a very generous definition of "complete", anyway) Ruby
implementation I know of which has its own parser. (Tinyrb has its own
parser, but it doesn't have full syntax compatibility as a goal
anyway. Cardinal also has its own parser, AFAIK, but it's a *loong*
way from being syntax-complete.)

jwm

Try:

puts((nil or 4))

I found a discussion of this in:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/38272

···

On Dec 30, 2009, at 9:24 PM, Albert Schlef wrote:

(The problem is in both Ruby 1.8 and Ruby 1.9)

The expression:

puts(nil || 4)

works as expected. It prints '4'.

But this expression:

puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

Why? I thought the only diference between "or" and "||" is the
precedence.

yes, so you can do eg

system "pwd" or raise "no command here"

/home/botp
=> true

system "asdf" or raise "no command here"

RuntimeError: no command here

if you know perl, this is no surprise..

as always, there are many ways in ruby, you can use || or the double
parens override.

happy holiday and best regards
-botp

···

On Thu, Dec 31, 2009 at 10:24 AM, Albert Schlef <albertschlef@gmail.com> wrote:

Hi,

(The problem is in both Ruby 1.8 and Ruby 1.9)

The expression:

  puts(nil || 4)

works as expected. It prints '4'.

But this expression:

  puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

There's a difference between _grouping_ parentheses (like
begin...end) and _method_ _call_ parentheses:

  puts (nil or 4) # vs.
  puts( nil or 4)

See:

  irb(main):001:0> $-w = true
  => true
  irb(main):002:0> puts( nil or 4)
  SyntaxError: compile error
  (irb):2: syntax error, unexpected kOR, expecting ')'
  puts( nil or 4)
              ^
          from (irb):2
  irb(main):003:0> puts (nil or 4)
  (irb):3: warning: (...) interpreted as grouped expression
  4
  => nil

Bertram

···

Am Donnerstag, 31. Dez 2009, 11:24:26 +0900 schrieb Albert Schlef:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
*
Support `String#notempty?': <http://raa.ruby-lang.org/project/step&gt;\.

Hm, on Ruby 1.9.1 I get:
irb(main):001:0> puts nil or 4

=> 4

Note that this is equivalent to "puts nil" followed by "4".

That's significant.

Consider:
  irb(main):001:0> x = nil or 4
  => 4
  irb(main):002:0> x
  => nil

The grouping is:
  (x = nil) or (4)

Or
  (puts nil) or (4)

This seems like a bug to me, since parenthesis *should* "only" make
method calls and precedent unambigious.

I believe that's precisely the problem -- the precedence of "or" is
low enough that it can't occur inside a method argument.

Compare this with the similar situation in C, where a comma operator
cannot occur inside an argument list for a function, because it's part
of the function-call syntax. So:

valid C:
  x = 1, y = 2;

(this performs both assignments, and returns the value of y after the
assignment, which happens to be 2.)

printf("%d\n", x = 1, y = 2);

This probably prints 1, but I think it's undefined behavior because there's
excess arguments to printf. (I'm not sure whether that's permitted or not,
but my guess would be "no, but it probably always works".)

So try:

  irb(main):003:0> puts( (nil or 4) )
  4
  => nil

Basically, if you really want parentheses (as in the precedence-changing
operator), you need to include them... Not merely put something that can't
go in a method argument list inside the confusingly-similar-looking
() which surround method arguments.

-s

···

On 2009-12-31, Phillip Gawlowski <pg@thimian.com> wrote:
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!

Specifically, the parens around the method call. Want to see something even
weirder?

irb(main):001:0> puts(nil or)
SyntaxError: (irb):1: syntax error, unexpected keyword_or, expecting ')'
puts(nil or)
           ^
        from /home/ruby19/bin/irb:12:in `<main>'
irb(main):002:0> puts(nil or 4)
SyntaxError: (irb):2: syntax error, unexpected keyword_or, expecting ')'
puts(nil or 4)
           ^
        from /home/ruby19/bin/irb:12:in `<main>'
irb(main):003:0> (nil or 4)
=> 4
irb(main):004:0> puts((nil or 4))
4
=> nil
irb(main):005:0>

···

On Wednesday 30 December 2009 08:35:43 pm Phillip Gawlowski wrote:

On 31.12.2009 03:24, Albert Schlef wrote:
> (The problem is in both Ruby 1.8 and Ruby 1.9)
>
> The expression:
>
> puts(nil || 4)
>
> works as expected. It prints '4'.
>
> But this expression:
>
> puts(nil or 4)
>
> fails... it is a syntax error, for some mysterious reason.
>
> Why? I thought the only diference between "or" and "||" is the
> precedence.

Hm, on Ruby 1.9.1 I get:
irb(main):001:0> puts nil or 4

=> 4
irb(main):002:0> puts(nil or 4)
SyntaxError: (irb):2: syntax error, unexpected keyword_or, expecting ')'
puts(nil or 4)
            ^
         from C:/Ruby19/bin/irb:12:in `<main>'
irb(main):003:0> puts(nil || 4)
4
=> nil

Gary Wright wrote:

···

On Dec 30, 2009, at 9:24 PM, Albert Schlef wrote:

puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Try:

puts((nil or 4))

I found a discussion of this in:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/38272

Thanks.

So it seems Ruby internally recognizes some structures as "statemenets"
and others as "expressions". It seems disapointing at first, but since
Ruby supports precedence for operators (something Lisp doesn't), there
has to be some price to pay.
--
Posted via http://www.ruby-forum.com/\.

botp wrote:

Why? I thought the only diference between "or" and "||" is the
precedence.

yes, so you can do eg

system "pwd" or raise "no command here"

/home/botp
=> true

system "asdf" or raise "no command here"

RuntimeError: no command here

if you know perl, this is no surprise..

It *is* a surprise. In Perl, unlike in Ruby, `func(0 or 1)` *does*
work....

as always, there are many ways in ruby, you can use || or the double
parens override.

Well. it turns out there aren't that many ways in ruby.

I originally tried to do the following:

  some_func(ARGV[0] or raise "You must provide an argument")

I wish it worked. But it doesn't. So I changed it to:

  some_func(ARGV[0] || raise "You must provide an argument")

It still didn't work. So finally I did:

  some_func(ARGV[0] || (raise "You must provide an argument"))

It works. But, I must say, it isn't as beautiful as my original plan. It
doesn't read as English.

···

On Thu, Dec 31, 2009 at 10:24 AM, Albert Schlef <albertschlef@gmail.com> > wrote:

--
Posted via http://www.ruby-forum.com/\.

botp :

Why? I thought the only diference between "or" and "||" is the
precedence.

yes, so you can do eg

system "pwd" or raise "no command here"

/home/botp
=> true

system "asdf" or raise "no command here"

RuntimeError: no command here

if you know perl, this is no surprise..

I know Perl, but I'm still surprised.

# perl -le 'print undef or 4'

# perl -le 'print(undef or 4)'
4

# irb
irb(main):001:0> puts nil or 4

=> 4
irb(main):002:0> puts(nil or 4)
SyntaxError: (irb):2: syntax error, unexpected keyword_or, expecting ')'
puts(nil or 4)
            ^
         from /usr/bin/irb:12:in `<main>'

And if I "puts (nil or 4)" (there is a blank between them) will print 4.
(Just my thought,I was thinking this is a bug.)

Regards,
Jeff.

···

On Thu, Dec 31, 2009 at 10:24 AM, Albert Schlef <albertschlef@gmail.com> wrote:

We do not all use the same parser. At the very least, they're all
written in our local language. We use parsers that were originally
ports of the original parser, and while changing over the years still
match MRI's parser behavior.

If MRI and YARV do it, then we do it because that's what MRI and YARV do.

Minor nitpick :slight_smile:

- Charlie

···

2009/12/30 Jörg W Mittag <JoergWMittag+Ruby@googlemail.com>:

Albert Schlef wrote:

[...]
puts(nil or 4)

fails... it is a syntax error, for some mysterious reason.

Why? I thought the only diference between "or" and "||" is the
precedence.

Looks like a genuine bug to me. I can verify that behavior in MRI,
YARV, JRuby, IronRuby and Rubinius (which is not terribly surprising
since they all use the exact same parser).

Bertram Scharpf wrote:
[...]

See:

  irb(main):001:0> $-w = true

[...]

  irb(main):003:0> puts (nil or 4)
  (irb):3: warning: (...) interpreted as grouped expression
  4

Thanks, I didn't know of this $-w trick.

···

--
Posted via http://www.ruby-forum.com/\.

Albert Schlef wrote:

Well. it turns out there aren't that many ways in ruby.

I originally tried to do the following:

  some_func(ARGV[0] or raise "You must provide an argument")

I wish it worked. But it doesn't. So I changed it to:

  some_func(ARGV[0] || raise "You must provide an argument")

It still didn't work. So finally I did:

  some_func(ARGV[0] || (raise "You must provide an argument"))

It works. But, I must say, it isn't as beautiful as my original plan. It
doesn't read as English.

Hey, I now see that this works:

    some_func((ARGV[0] or raise "You must provide an argument"))

Great. On the other hand, I won't be able to remember this the next time
I need it.

···

--
Posted via http://www.ruby-forum.com/\.

I don't think that's it at all. I think it's that methodname( is a method
call (), not a grouping (). Thus the difference between
  puts(a or b)
and
  puts (a or b)

In short, it's nothing to do with statements-vs-expressions, and everything
to do with disambiguating method calls vs. parenthesized expressions.

-s

···

On 2009-12-31, Albert Schlef <albertschlef@gmail.com> wrote:

So it seems Ruby internally recognizes some structures as "statemenets"
and others as "expressions". It seems disapointing at first, but since
Ruby supports precedence for operators (something Lisp doesn't), there
has to be some price to pay.

--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!

PS C:\Scripts> ruby .\unless.rb
./unless.rb:1: Argument error (RuntimeError)
PS C:\Scripts> ruby .\unless.rb "arg"
PS C:\Scripts> cat .\unless.rb
raise "Argument error" unless ARGV[0]
PS C:\Scripts>

I prefer it that way. :slight_smile:

Works in 1.8.6 and 1.9.1, too, to my great relief.

···

On 31.12.2009 06:32, Albert Schlef wrote:

It works. But, I must say, it isn't as beautiful as my original plan. It
doesn't read as English.

--
Phillip Gawlowski

And you can even omit the method brackets as in

irb(main):001:0> puts (nil or 4)
4
=> nil

Kind regards

  robert

···

On 12/31/2009 03:43 AM, Seebs wrote:

On 2009-12-31, Phillip Gawlowski <pg@thimian.com> wrote:

Hm, on Ruby 1.9.1 I get:
irb(main):001:0> puts nil or 4

=> 4

Note that this is equivalent to "puts nil" followed by "4".

That's significant.

Consider:
  irb(main):001:0> x = nil or 4
  => 4
  irb(main):002:0> x
  => nil

The grouping is:
  (x = nil) or (4)

Or
  (puts nil) or (4)

This seems like a bug to me, since parenthesis *should* "only" make method calls and precedent unambigious.

I believe that's precisely the problem -- the precedence of "or" is
low enough that it can't occur inside a method argument.

Compare this with the similar situation in C, where a comma operator
cannot occur inside an argument list for a function, because it's part
of the function-call syntax. So:

valid C:
  x = 1, y = 2;

(this performs both assignments, and returns the value of y after the
assignment, which happens to be 2.)

printf("%d\n", x = 1, y = 2);

This probably prints 1, but I think it's undefined behavior because there's
excess arguments to printf. (I'm not sure whether that's permitted or not,
but my guess would be "no, but it probably always works".)

So try:

  irb(main):003:0> puts( (nil or 4) )
  4
  => nil

Basically, if you really want parentheses (as in the precedence-changing
operator), you need to include them... Not merely put something that can't
go in a method argument list inside the confusingly-similar-looking
() which surround method arguments.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Well. it turns out there aren't that many ways in ruby.

I originally tried to do the following:

some_func(ARGV[0] or raise "You must provide an argument")

First off, I'd say that this is probably confusing form to use. If I
ever saw this in code I'd write it differently.

I wish it worked. But it doesn't. So I changed it to:

some_func(ARGV[0] || raise "You must provide an argument")

It still didn't work. So finally I did:

some_func(ARGV[0] || (raise "You must provide an argument"))

It works. But, I must say, it isn't as beautiful as my original plan. It
doesn't read as English.

This isn't too bad, for what you want:

some_func ARGV[0] || raise('you must provide an argument')

or:

some_func(ARGV[0] || raise('you must provide an argument')

And if I were to write this, I'd probably choose one of these variants:

ARGV[0] ? some_func(ARGV[0]) : raise 'you must provide an argument'

or

raise 'you must provide an argument' unless ARGV[0]
some_func(ARGV[0])

- Charlie

···

On Wed, Dec 30, 2009 at 11:32 PM, Albert Schlef <albertschlef@gmail.com> wrote:

Hi --

···

On Thu, 31 Dec 2009, Albert Schlef wrote:

Well. it turns out there aren't that many ways in ruby.

I originally tried to do the following:

some_func(ARGV[0] or raise "You must provide an argument")

I wish it worked. But it doesn't. So I changed it to:

some_func(ARGV[0] || raise "You must provide an argument")

It still didn't work. So finally I did:

some_func(ARGV[0] || (raise "You must provide an argument"))

It works. But, I must say, it isn't as beautiful as my original plan. It
doesn't read as English.

It's not supposed to; it's supposed to read as Ruby :slight_smile: I wouldn't
make too much of the English-likeness. I think of it more as an
emergent thing than as a style guideline.

David

--
David A. Black
Senior Developer, Cyrus Innovation Inc.
THE COMPLEAT RUBYIST, Ruby training with Black/Brown/McAnally!
January 22-23, Tampa, Florida
Info and registration at http://www.thecompleatrubyist.com

I know Perl, but I'm still surprised.

# perl -le 'print undef or 4'

# perl -le 'print(undef or 4)'
4

do not be surprise, ruby opted for the former case since it is more
common, and therefore has relegated the "or/and" ops w very low
precedence level (and ergo different fr their sibling ops "||/&&")

in other words, if you see a method like

puts 1,2 or 4

1
2
=> 4

it actually means

puts( 1,2) or 4

1
2
=> 4

and if you write a statement like

puts( 1,2 or 4)

ruby will err for you
but friendly enough to allow you to by (re)emphasizing...

so maybe you meant

puts( 1, (2 or 4))

best regards
-botp

···

On Thu, Dec 31, 2009 at 3:13 PM, Jeff Peng <jeffpeng@netzero.net> wrote: