Thomas Schlereth Thomas Schlereth - 1 month ago 8
Ruby Question

Ruby binary method <<=

This is several questions wrapped in one. I saw the method "<<=" used recently. I was able to piece together what is does, but not anything else about it.

$ dec = 2
$ dec <<= 1
=> 4
$ dec
=> 4
$ dec <<= 2
=> 16


I think it's basically a shortcut for multiplying the sum plus the next nth position's in binary:

$ a = 2 * 2 ** 1
=> 4
$ a = a * 2 ** 2
=> 16


It doesn't work if you try it on a fixnum itself

$ 4 <<= 1
=> SyntaxError: unexpected tOP_ASGN, expecting end-of-input
1 <<= 1
^


I searched for hours and couldn't find where it lives in the ruby docs.


  • Where is there documentation for this?

  • What class or module does this live in?

  • Why does is only work if you assign it to a variable first?



Thanks!

Answer

This is called an abbreviated assignment and is covered in section 11.4.2.3 Abbreviated Assignments of the ISO Ruby Language Specification; specifically it is an abbreviated variable assignment (§11.4.2.3.2).

An abbreviated variable assignment is evaluated (roughly) like this:

a ω= b

is the same as

a = a ω b

where ω is an arbitrary non-equality Ruby operator (&&, ||, &, |, ^, +, -, *, /, **, %, <<, >>).

Note: this simple translation applies only to abbreviated variable assignments. It does not apply to abbreviated indexing assignments (a[b] ω= b) or abbreviated method assignments (a.b ω= c).

  • Where is there documentation for this?

While the ISO Ruby Language Specification covers only a small subset of the intersection of Ruby 1.8 and Ruby 1.9, abbreviated assignments are covered there.

They are also covered in the Ruby RDocs under syntax/assignment.rdoc.

  • What class or module does this live in?

None. Assignments are a language feature, not a library feature.

  • Why does is only work if you assign it to a variable first?

I am not sure what you mean. It works perfectly fine without assigning to a variable first:

class NilClass; def <<(*) :haha end end

a <<= a
#=> :haha