4

Why can't I call Enumerable#reduce(sym) without parentheses like the following?

>> [1, 2, 3].reduce :+
?>

While using parentheses results in this:

>> [1, 2, 3].reduce(:+)
=> 6

Am I accidentally calling Enumerable#reduce {| memo, obj | block } instead?

Furthermore, why does this happen?

>> [1, 2, 3].reduce &:+
?> ^C
>> [1, 2, 3].reduce(&:+)
=> 6

Thanks a lot!

cyang
  • 5,574
  • 2
  • 25
  • 34

2 Answers2

7

That seems to be an error in IRb's parser. It works just fine if you try it in Pry, or on the commandline or in a file:

ruby -e"res = [1, 2, 3].reduce :+
p res"
# 6

Basically, IRb gets confused, thinks the + is a binary operator and is waiting for the second operand.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • +1 I didn't know there was such a thing as Pry. Also, I didn't think to check it from a file. Thanks! – cyang Aug 03 '12 at 00:44
  • Note: I originally had `res = [1, 2, 3].reduce :+; p res` as an example, but it turns out that IRb can handle that just fine. It needs the newline to trigger the error. – Jörg W Mittag Aug 03 '12 at 00:44
  • I had tried `res = [1, 2, 3].reduce :+;` previously, but it just gave me the `?>` prompt. I didn't think to try typing `p res` afterward. – cyang Aug 03 '12 at 00:46
  • 2
    At the moment, Pry is basically a faster, better, more powerful, more featureful, better maintained, actively developed alternative to IRb. However, the *real* goal for it is to evolve into a Smalltalk/Lisp-style interactive development experience / IDE. It already has some interactive exploration capabilities, e.g. you can `cd` into an object and `ls` its instance variables, you can show the documentation or the source code for methods etc. – Jörg W Mittag Aug 03 '12 at 00:47
0

It would seem the Ruby parser can't deal with that particular combination. Symbols have limitations, but :+ and the like are some kind of special case that apparently requires brackets to be properly interpreted.

Notice if you try and evaluate :+ by itself it doesn't parse. The same goes for other operators like :* and :/ so something "magical" is going on here.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 3
    Ruby's parser handles this just fine. The problem is IRb's parser, which is basically a hodge-podge of `Regexp`s duct-taped together to parse something which hopefully but not quite exactly resembles the Ruby language. Pry uses YARV's, JRuby's or Rubinius's builtin parser instead, which is by definition always correct. – Jörg W Mittag Aug 03 '12 at 00:40
  • That would be a more reasonable explanation. I've never seen `irb` diverge from the Ruby interpreter that dramatically before, but then again, I'm a big fan of brackets. – tadman Aug 03 '12 at 00:59