Simon
Simon

Reputation: 25984

Why doesn't >> prepend strings in Ruby?

In ruby, you can append strings using <<:

>> "Hello" << "World"
=> "HelloWorld"

So why can't you prepend them using >>?

>> "Hello" >> "World"
NoMethodError: undefined method `>>' for "Hello":String

I realise String doesn't have the >> method defined, but what's the reasoning behind that?

Upvotes: 20

Views: 11676

Answers (5)

Patrick Smith
Patrick Smith

Reputation: 772

Ruby 1.9.3 added a String#prepend method.

The proposal about adding prepend[1] also included the ">>" method, and there's some discussion on the thread about that implementation [2]:

Matz says: " >> is interesting notation did not think about it."

sorya says: "This patch is out it had been discussed several times towards the IRC"

However at the end of the thread, the conclusion was to accept String#prepend, and that "other proposals including String # >> are pending."

I couldn't find any other discussion about it though... anyone else?

Personally, I like it, and it's trivial to add:

class String
  def >> (s)
    s.prepend(self)
  end
end

The result:

>> "Hello" >> "World"
=> "HelloWorld"

[1] http://bugs.ruby-lang.org/issues/3675

[2] http://translate.google.com/translate?hl=en&sl=ja&tl=en&u=http%3A%2F%2Fbugs.ruby-lang.org%2Fissues%2F3675

Upvotes: 26

clem
clem

Reputation: 3534

I don't think I would do this, but if someone forced me to:

class String
  def prepend(string)
    insert(0, string)
  end
end

I don't think >> is a good idea—the reason << is nice is because it looks like what's going to happen. >> looks like it would have the same result as << to me, except that the calling object is being prepended onto the parameter.

Upvotes: 1

sawa
sawa

Reputation: 168081

I think this is a good question, and the issue is more general than just the problem with the notation << as suggested in McStretch's answer because there is a same situation with the methods given in an alphabet. Namely, there is String#concat, which appends an argument string to self, but there is no method that prepends an argument string.

Upvotes: 0

McStretch
McStretch

Reputation: 20645

Ruby's syntax wouldn't allow a method like >> to be implemented the way you expect.

<< in "Hello" << "World" is equivalent to the following:

"Hello".<<("World")

If you wanted to create a prepend method >>, I would expect "Hello" in "Hello" >> "World" to be the argument to the string "World":

("Hello")>>."World" which isn't valid Ruby syntax.

If "World" was an argument to "Hello", then you would just be appending a string like fl00r demonstrated. Aliasing >> to mean the same as << would cause confusion.

This is why you have the insert method instead. If you want to insert "Hello" in front of "World" you would call insert on "World":

"World".insert(0, "Hello ")

The takeaway here is to keep in mind that << is a method call just like a string method such as length, so you have to keep the ordering similar to regular method calls.

Upvotes: 20

fl00r
fl00r

Reputation: 83680

Ruby always asigns value from the right to the left.

But you can implement it by yourself

class String
  def >>(s)
    s << self
  end
end

"Hello" >> "world"
#=> "worldHello"

Upvotes: 6

Related Questions