Meaning of "<<"?

Discussion in 'Ruby' started by Chris Davies, Feb 13, 2009.

  1. Chris Davies

    Chris Davies Guest


    I'm currently trying to learn ruby, coming from a perl/unix
    background. I've been working through one of the many online tutorials
    and it's suddenly thrown in the "<<" operator.

    Now, I'm familiar with a the use of "<<" as a bitwise left shift
    and as a here doc, but this one throws me. The relevant URL is
    and here's a variation on the theme for illustrative purposes:

    str = 'one'
    str << 'two'
    puts str # onetwo

    It seems to me that << in this context is equivalent to +=, but I can't
    find any documentation explaining /why/ this is the case, and why I
    should use one in preference to the other. (Google really doesn't like

    Any suggestions, please?
    Chris Davies, Feb 13, 2009
    1. Advertisements

  2. [Note: parts of this message were removed to make it a legal post.]

    Hi Chris,
    If you see the string class documentation of ruby,
    Its for concatenation..
    You may find more here

    Thanks and Regards
    Saurabh Purnaye
    skype: sorab_pune
    yahoo & gtalk: saurabh.purnaye
    saurabh purnaye, Feb 13, 2009
    1. Advertisements

  3. Chris Davies

    Dido Sevilla Guest

    Ruby is capable of doing operator overloading, and the << operator has
    been consistently overloaded to do stuff like appending data (I
    believe this was an idea that came from C++). Note also that use of <<
    on strings is much faster than +=3D, since +=3D will create a new string,
    append the string you're adding to it, and replace the old string by
    the new one, while, if I'm not mistaken << will append the data on its
    right side in place, if I recall correctly.

    Several other classes also overload the << operator. Using << on an
    array will append the right hand side to the end of the array
    (equivalent to Array#push). << on an IO object will write the object
    on the right hand side, converting it to a string, just as someone
    coming from C++ might expect.

    Dido Sevilla, Feb 13, 2009
  4. Alle Friday 13 February 2009, Chris Davies ha scritto:
    This is the documentation for the String << operator (that is, for the
    String#<< method):

    str << fixnum => str
    str.concat(fixnum) => str
    str << obj => str
    str.concat(obj) => str

    From Ruby 1.8
    Append---Concatenates the given object to _str_. If the object is a
    +Fixnum+ between 0 and 255, it is converted to a character before

    a = "hello "
    a << "world" #=> "hello world"
    a.concat(33) #=> "hello world!"

    The difference between << and + is that << modifies the first string, while +
    creates a new string, made of the caracters of the first string followed by
    the characters of the second. Too see the difference, look at this example:

    a = "first string"
    b = "second string"
    puts "Using +"
    a + b
    puts a
    puts b
    puts "Using <<"
    a << b
    puts a
    puts b

    The output is:

    Using +
    first string
    second string
    Using <<
    first stringsecond string
    second string

    As you can see, in the second case, a has been modified, while in the first
    case it wasn't.

    In general, to obtain documentation about ruby classes and methods, you can
    use the ri command:

    ri 'String#<<'

    which will give the documentation I posted above. There's also an online API
    reference at

    I hope this helps

    Stefano Crocco, Feb 13, 2009
  5. Chris Davies

    Chris Davies Guest

    Thank you all. Very enlightening.
    Chris Davies, Feb 13, 2009

  6. Think of it as a method, not as an operator.
    Every class can define a method that is called '<<'
    just like any class can define a method called 'print' or 'count'.

    Don't let this syntax fool you:

    str = "basic"
    str << "appended"

    It is just a nice to read way of saying the
    following, which explains it and works, too:

    str = "basic"
    str.<<( "appended" )

    Got it?

    Herman Martinelli, Feb 13, 2009
  7. Julian Leviston, Feb 14, 2009
  8. I thought operator overloading was a non-oop way of specifying
    multiple functions that each take different argument numbers? That's
    not what's going on here. This is messages having the same name
    exactly being sent to different classes having slightly different
    meanings depending on the class of the receiver. It's encapsulation,
    really... Each class encapsulates its meanings and can obviously have
    different meanings for the same method names depending on the classes
    in question.

    Learn rails:
    Julian Leviston, Feb 14, 2009
  9. Chris Davies

    Gary Wright Guest

    Agreed. This is not 'overloading' in the C++ sense of the term.
    Disagree. Encapsulation doesn't seem like the right concept to
    describe this pattern.

    I think that 'abstraction' might be a better description. When the
    same method provides analogous semantics across multiple classes, the
    method name becomes a sigil for the abstract semantics. So '<<' is a
    sigil for 'alter via concatenation' (IO, String, Array) but is also a
    sigil for 'shift to the left' (Fixnum, Date, IPAddr).

    The term 'protocol' is often used to describe this sort of pattern
    across classes.

    Good library design comes from exploiting these sorts of patterns.

    Gary Wright
    Gary Wright, Feb 14, 2009
  10. Chris Davies

    Chris Davies Guest

    More syntatic sugar, like the "def instance_var=" setter method?

    Chris Davies, Feb 14, 2009
  11. Chris Davies

    7stud -- Guest

    That's called *function* overloading. In C++, function overloading and
    operator overloading are two different things. Operator overloading
    requires a specific function signature for a given operator. Function
    overloading on the other hand is used to create multiple function
    signatures for a given function name.
    7stud --, Feb 14, 2009
  12. Julian Leviston, Feb 14, 2009
  13. [Note: parts of this message were removed to make it a legal post.]

    That's not the way I see it. In C++ operator overloading is accomplished by
    defining an overloaded function with special syntactic sugar to give it the
    same name as an existing operator:


    Class Complex {
    Complex operator+(int);
    Complex operator+(double);
    Complex plus(int);
    Complex plus(double);

    This class declares that it has both overloaded versions of the binary +
    operator as well as of the plus member function.

    Operator overloading
    As indicated above, they both do this.

    Overloading means that the compiler distinguishes at compile time between
    calls to the same function or operator with the same name, based on the
    type(s) of the arguments.

    As this depends on having static types, overloading, either of functions or
    operators really isn't a concept which is applicable to dynamically typed
    languages like Ruby. Use cases like mixed-mode arithmetic are handled by
    different techniques like the Numeric.coerce method in Ruby or double
    dispatching in Smalltalk.

    A side note on C++. Overloading is one of the mechanisms C++ provides to
    define polymorphism. Virtual functions are another, and probably better
    known, Virtual functions can be overridden (which is different from
    overloaded) by providing a new implementation in a subclass. Although
    virtual functions can be overloaded, it's not for the faint of heart:

    It's a good example of why, when you scratch a little below the surface,
    statically typed languages like C++ and dynamically typed language like Ruby
    are very different beasts and it's dangerous to try to apply knowledge of
    one to the other without some deep thinking.
    Rick DeNatale, Feb 14, 2009
  14. Chris Davies

    7stud -- Guest

    I stand corrected. Thank you.
    7stud --, Feb 14, 2009
  15. Chris Davies

    Ken Bloom Guest

    Ruby restricts you to defining operators in the class of the left-hand
    side object. C++ has no such restriction. You could presume that in C++,
    the + operator is defined in the global namespace as:

    int operator + (int, int)
    double operator + (double, double)
    double operator + (int, double)
    double operator + (double, int)

    Thus, when you create a class Date and define the + operator as
    Date operator + (Date const &, int)
    you really are overloading the + operator (in the function overloading
    sense of the term).

    C++ also allows you to define
    class Date{
    Date operator+ (int);
    which equivalent to the global namespace version, and the name operator
    overloading comes along for the ride.

    Ruby, which is more restrictive, doesn't have function overloading at
    all, so operator overloading has taken on a new meaning (simply
    redefining the operator on a new class) that's a bit of a misnomer if you
    try to relate it back to the C++ term whence it originated.

    Ken Bloom, Feb 16, 2009
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.