Что означает массив * string в Ruby? - PullRequest
13 голосов
/ 10 февраля 2010

Я просматривал исходный код Rails и наткнулся на

# File vendor/rails/activesupport/lib/active_support/vendor/builder-2.1.2/builder/css.rb, line 129
129:     def target!
130:       @target * ''
131:     end

Что делает * ''? Это умножение на пустую строку ...? И зачем ты это делаешь.

Ответы [ 6 ]

13 голосов
/ 10 февраля 2010

Это странный синтаксис. Это эквивалентно:

>> [1, 2, 3] * 'joiner'
=> "1joiner2joiner3"

>> [1, 2, 3].join 'joiner'
=> "1joiner2joiner3"

, поэтому в этом случае он объединяет все записи @target в одну строку, между которыми ничего нет.

Примечание: если вы сделаете что-то вроде [1, 2, 3] * 3 (используя int вместо str), вы получите три сцепленных копии массива.

5 голосов
/ 10 февраля 2010

Он делает то же самое, что и:

["foo","bar","baz"].join

http://ruby -doc.org / ядро ​​/ классов / Array.html # M002210

Согласно предложению Z.E.D., вы бы использовали его, если хотите запутать людей и сделать свой код более подверженным ошибкам.

3 голосов
/ 10 февраля 2010

Действительно действительно загадочный код.

После проверки исходного кода я понял, что @target на самом деле Array экземпляр, я знаю, что вы можете делать такие вещи, как это

[5] * 5 # => [5,5,5,5,5]

Я не знаю, где определяется Array#* (возможно, в ActiveSupport), но я могу сказать вам, что это поведение, когда оно умножается на String

[1,2,3] * 'comma' # => "1comma2comma3"
[1,2,3] * '' # => '123'

Таким образом, я могу заключить, что он объединяет все элементы массива без разделителей.

2 голосов
/ 10 февраля 2010

Array#* с аргументом String эквивалентно Array#join.

1 голос
/ 10 февраля 2010

Два комментария:

  1. Имея!end имя метода подразумевает, что это мутирующая операция, которой в этом примере это не выглядит.

  2. Как уже говорили другие, это действительно загадочно.Я бы пошел на @ target.to_s или @ target.join

0 голосов
/ 06 июня 2011

Единственная причина, по которой я вижу, что кто-то хочет использовать * для присоединения к массиву строк, заключается в том, что он хочет избежать слова join, которое также используется в потоках.

Сследующее:

strings = ["John", "Smith"]
threads = [Thread.new{puts "hai"}, Thread.new{ puts "world!"}]
strings.join(" ") # Legit
threads.each {|thread| thread.join} # Legit

вы можете ошибиться, если сделаете

threads.join # Not legit, but won't raise an error

Если вы замените strings.join на strings.*, то у вас будет меньше join скод.Теперь вы можете сделать для них grep и проверить, что каждый выполняется с потоком, а не с массивом.На самом деле, вы можете сделать Array#join сгенерировать исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...