12

If I do this:

(false true)

it fails with a syntax error, as I expect. But if I do this:

(false
 true)

the code is executed, and it throws away the first condition and returns the result of the second.

Is this considered a bug or a feature?

sawa
  • 165,429
  • 45
  • 277
  • 381
L2G
  • 846
  • 6
  • 28
  • 2
    I knew there had to be a simple explanation. You should post this as a real answer and claim some credit for yourself. :-) – L2G Dec 07 '11 at 20:05

3 Answers3

15

Line endings are optional, so in this case, the return is causing the parser to interpret it as the following:

(false; true)

which evaluates to just:

(true)

If these were method calls then both would be evaluated, but only the last would be emitted. For example:

x = (p "hello"
p "world"
2)

This will output "hello" and "world" and x will equal 2

J. Holmes
  • 18,466
  • 5
  • 47
  • 52
7

Parentheses are used for grouping, line breaks are used as expression separators. So, what you have here is simply a group of two expressions. There is nothing to reject.

This is useful because of this well-known idiom:

def foo(bar = (bar_set = true; :baz))
  if bar_set
    # optional argument was supplied
  end
end

There is simply no other way in Ruby to figure out whether an optional argument was supplied or not.

Basically, this becomes interesting in the presence of side effects, such as assigning a variable in my example or printing to the screen in @32bitkid's example. In your example, there is no side effect, that's why you couldn't see what was actually going on.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Actually, that idiom is new to me, so I appreciate your answer! – L2G Dec 07 '11 at 20:55
  • @L2G: It's not used very often, but there are some standard protocols which require distinguishing between whether or not an optional argument was supplied. `inject` is an example. Usually it is implemented in C or Java or C#, with privileged access to the interpreter internals, which makes it easy to check for the existence of an optional argument. But if you want to duplicate its behavior in pure Ruby, you have to resort to tricks like this. – Jörg W Mittag Dec 07 '11 at 21:23
2

Ruby can give you a warning if you have warnings on.

$VERBOSE = true
def foo
  (false
   true)
end

gives you

(irb):3: warning: unused literal ignored

In both Ruby 1.9.1 patchlevel 378 and Ruby 1.8.7 patchlevel 330.

See How can I run all Ruby scripts with warnings? for how to run all Ruby scripts with warnings on.

Community
  • 1
  • 1
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338