.subst
- это метод Str .
Это означает, что он предполагает, что его первый аргумент (инвокант) является Str .Если это еще не Str , оно преобразуется в Str .
Когда вы вызываете .Str
для массива, он объединяет все значения вместес пробелом в качестве разделителя.
my @a = < a b c >;
say @a.perl; # ["a", "b", "c"]
say @a.Str.perl; # "a b c"
Таким образом, эти три строки в точности эквивалентны:
@a.subst(/<[aeiou]>/, 1, :g);
@a.Str.subst(/<[aeiou]>/, 1, :g);
@a.join(" ").subst(/<[aeiou]>/, 1, :g);
Perl6 делает это, потому что он непротиворечив.Вы всегда знаете, что вывод одного вызова .subst
- это один Str .Вы также знаете, что инвокант обрабатывается как Str .
Если бы он делал что-то другое с массивами, стало бы трудно отследить, какие методы меняются в зависимости от того, кто там работает, и как ониизменить.
Нам нужно только взглянуть на Perl5, чтобы увидеть, как трудно запомнить каждую причуду каждой функции, когда они не согласованы.
(Попробуйте подумать обо всех функциях в Perl5, которыеработать с $_
по умолчанию, и то, что они делают в контексте скаляра и списка.)
Вместо вызова .subst
для одного значения массива, вы хотите вызвать его для каждого иззначения, которые он содержит.
Есть несколько способов сделать это:
my @ = @a.map( *.subst(…) )
my @ = @a».subst(…)
my @ = do for @a { .subst(…) }
my @ = @a.duckmap( -> Str $_ { .subst(…) } ) # only change Str's