Что означает строка * массива в Ruby?
Я просматривал исходный код 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
Что делает * ''? Это умножение на пустую строку...? И почему бы вам это сделать.
Ответы
Ответ 1
Это странный синтаксис. Они эквивалентны:
>> [1, 2, 3] * 'joiner'
=> "1joiner2joiner3"
>> [1, 2, 3].join 'joiner'
=> "1joiner2joiner3"
поэтому в этом случае он объединяет все записи @target
в одну строку, между элементами ничего нет.
Примечание: если вы делаете что-то вроде [1, 2, 3] * 3
(используя int
вместо str
), вы получите вместо него три конкатенированные копии массива.
Ответ 2
Он делает то же самое, что:
["foo","bar","baz"].join
http://ruby-doc.org/core/classes/Array.html#M002210
Per Z.E.D. вы можете использовать его, если хотите запутать людей и сделать свой код более подверженным ошибкам.
Ответ 3
Действительно критический код.
После проверки исходного кода я понял, что @target
на самом деле является экземпляром Array
, я знаю, что вы можете делать такие вещи как
[5] * 5 # => [5,5,5,5,5]
Я не знаю, где Array#*
определено (возможно, в ActiveSupport
), но я могу сказать вам, что это поведение, когда оно умножается на String
[1,2,3] * 'comma' # => "1comma2comma3"
[1,2,3] * '' # => '123'
Поэтому я могу заключить, что он объединяет все элементы массива без каких-либо разделителей.
Ответ 4
Array#*
с аргументом String
эквивалентен Array#join
.
Ответ 5
Два комментария:
-
Имея! end имя метода подразумевает, что оно является мутационной операцией, которая, как представляется, не является.
-
Как утверждают другие, это действительно загадочно. Я бы пошел на @target.to_s или @target.join
Ответ 6
Единственная причина, по которой я хочу увидеть, что кто-то хочет использовать *
для соединения с массивом строк, - это если они хотят избежать слова 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
исключение.