2

I am getting bizzare output in irb

>> [1, 2] + + [3]
NoMethodError: undefined method `+@' for [3]:Array
    from (irb):2
    from /home/marko/.rubies/ruby-2.3.1/bin/irb:11:in `<main>'
>> [1, 2] ++ [3]
NoMethodError: undefined method `+@' for [3]:Array
    from (irb):3
    from /home/marko/.rubies/ruby-2.3.1/bin/irb:11:in `<main>'
>> 

Is this happening on purpose or is it a bug?
What's the logic behind converting + + into +@

Marko Avlijaš
  • 1,579
  • 13
  • 27
  • 4
    In the past year the authors of 453 SO questions suggested that unexplained behavior might be attributed to a bug in Ruby. The culprit was found to be something more mundane in 451 of those cases. – Cary Swoveland Mar 11 '17 at 15:27
  • http://ruby-doc.org/core-2.4.0/Numeric.html#method-i-2B-40 – Sagar Pandya Mar 11 '17 at 17:52

3 Answers3

9

It's not converting + + into +@, it's converting the latter + to +@, i.e. the prefix + operator. Thus the expression is parsed the same as [1, 2] + (+[3]).

(+@ is used to denote the unary plus operator because + is reserved for the binary plus operator.)

(Also, there's no ++ operator in Ruby.)

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
3

I believe that this is parsed as:

[1, 2] + +[3]

And the error is Ruby telling that there is no concept of a positive array.

You can see this with integers. For example:

1++2  # => 3
# parsed as 1 + +2
# (obviously this is a particularly bad way to write this expression - don't do it!)
gwcodes
  • 5,632
  • 1
  • 11
  • 20
0

As per this answer No increment operator (++) in Ruby? Ruby does not have an incremental operator, so at best + + will be interpreted as two separate operators, causing unexpected behavior. As

++ and -- are NOT reserved operator[s] in Ruby

it's possible that a Ruby gem or other included library could cause additional unexpected behaviour when attempting this operation. Also worth noting is that ++ or + +, which is functionally the same thing in a non white-space sensitive language like Ruby will fail to parse where there are no possible separate operations for both the + operators.

In short: Ruby does not interpret + + as +@, it merely interprets it as two separate + operators.

Community
  • 1
  • 1
  • 1
    This is misleading. First: Yes, Ruby *does* interpret it as two separate operators, but it interprets it as two *different* operators: binary infix `+` and unary prefix `+`. Second: the message corresponding to unary prefix `+` is called `+@`, so, yes, Ruby *does* interpret it as `+@`, specifically as `[1, 2].+([3].+@())`. – Jörg W Mittag Mar 12 '17 at 02:49
  • Is this always true, or just in certain situations? If the latter then my answer to the original question asked is accurate and should not be misleading, since it concerned a generalization made from a specific example, rather than the example itself -- though of course the tuple_cat answer from a more experienced dev with lower-level experience is worthy of its upvotes, imo. –  Mar 12 '17 at 15:17