Почему не >> добавляет строки в Ruby?
В ruby вы можете добавлять строки с помощью <<
:
>> "Hello" << "World"
=> "HelloWorld"
Итак, почему вы не можете добавить их с помощью >>
?
>> "Hello" >> "World"
NoMethodError: undefined method `>>' for "Hello":String
Я понимаю, что String
не имеет установленного метода >>
, но какова причина этого?
Ответы
Ответ 1
В Ruby 1.9.3 добавлен метод добавления строки String #.
В предложение о добавлении prepend [1] также включен метод " → ", и есть некоторое обсуждение потока об этой реализации [2]:
Мац говорит: " → Интересная нотация не думала об этом".
sorya говорит: "Этот патч из-за того, что он несколько раз обсуждался в IRC"
Однако в конце потока было принято решение принять String # prepend и что "другие предложения, включая String # → , находятся в ожидании".
Я не мог найти другого обсуждения об этом, хотя... кто-нибудь еще?
Лично мне это нравится, и это тривиально добавить:
class String
def >> (s)
s.prepend(self)
end
end
Результат:
>> "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
Ответ 2
Синтаксис Ruby не позволит реализовать такой метод, как >>
, как вы ожидаете.
<<
в "Hello" << "World"
эквивалентно следующему:
"Hello".<<("World")
Если вы хотите создать метод prepend >>
, я ожидал бы, что "Hello" в "Hello" >> "World"
будет аргументом строки "World"
:
("Hello")>>."World"
, который не является допустимым синтаксисом Ruby.
Если "Мир" был аргументом "Hello" , вы просто добавили бы строку типа fl00r. Алиасинг >>
означает то же самое, что и <<
может вызвать путаницу.
Вот почему у вас есть метод insert
. Если вы хотите вставить "Hello" перед "World", вы бы назвали insert в "World":
"World".insert(0, "Hello ")
Здесь следует помнить, что <<
- это вызов метода, как строковый метод, такой как length
, поэтому вам нужно поддерживать порядок, похожий на обычные вызовы методов.
Ответ 3
Ruby всегда присваивает значение справа налево.
Но вы можете реализовать его самостоятельно
class String
def >>(s)
s << self
end
end
"Hello" >> "world"
#=> "worldHello"
Ответ 4
Я не думаю, что я это сделаю, но если кто-то заставил меня:
class String
def prepend(string)
insert(0, string)
end
end
Я не думаю, что >>
- хорошая идея - причина <<
хороша, потому что похоже, что это произойдет. >>
выглядит так, что для меня будет иметь тот же результат, что и <<
, за исключением того, что вызывающий объект добавляется к параметру.
Ответ 5
Я думаю, что это хороший вопрос, и проблема более общая, чем проблема с обозначением <<
, как это было предложено в McStretch, потому что существует такая же ситуация с методами, указанными в алфавите. А именно, существует String#concat
, который присоединяет строку аргумента к self
, но нет метода, который добавляет строку аргумента.