Способы получения изменяемых строк из фрагментов объекта Match? - PullRequest
7 голосов
/ 26 июня 2019

Я пытаюсь отобразить чанки из объекта Match в массив Pairs с изменяемыми строковыми значениями - что, я полагаю, требует скаризации строк. Единственный способ понять, как это сделать, заключить их в квадратные скобки и проиндексировать:

 my @n =map { $_.key => [$_.value.Str][0] }, G::parse($str).chunks;

Скаляризация с помощью $ (..) не работала и не клонировала и тому подобное. Должен быть более канонический путь. И почему не работает $ (..) - разве не для этого?

Ответы [ 2 ]

8 голосов
/ 27 июня 2019

Несколько вещей, которые можно отменить здесь:

  • Все строки в P6 являются неизменяемыми.(Спасибо, Лиз. :)) Но вы, вероятно, не имеете в виду, что хотите получить изменяемую строку.Вы, вероятно, просто имеете в виду наличие строк в контейнерах, чтобы содержимое этих контейнеров можно было изменить.

  • Конструктор пар => не деконтейнереризирует свое правое значение, если он находится в контейнере.Таким образом, если bar является контейнером Scalar, содержащим строку, то foo => bar создает пару со значением, равным этому Scalar контейнеру, содержащему эту строку.

  • $(...)используется для заключения в скобки выражения, которое должно обрабатываться как единственное число, даже если это контейнер множественного числа.(Это отражает @(...), которое используется для заключения в скобки выражения, которое должно рассматриваться как множественное число, даже если оно является единственным контейнером или значением.)

  • Не удивительно, что вы подумали $(...) создаст Scalar контейнер.(В конце концов, %(...) создает Hash, так почему бы и нет?) Но вместо этого вы должны использовать Scalar декларатор.

  • Самый краткий Scalar декларатор предназначен для анонимное состояние Scalar с использованием $ = ....Но @ Håkon использовал my $ = ... в своем ответе.Зачем?Поскольку замыкание {...}, вызываемое map, сохраняет состояние между вызовами этого.Если вы используете только $ = ..., то вы будете использовать один и тот же контейнер Scalar для всех пар.Вместо этого вам нужно my $ = ..., чтобы получить новые Scalar s для значения каждой пары.

5 голосов
/ 26 июня 2019

Вы можете поместить неизменяемую строку в скалярный контейнер, выполнив:

my @n = map { $_.key => my $ = $_.value.Str }, G::parse($str).chunks;

затем вы можете позже изменить содержимое скалярного контейнера (но не содержимое строки):

@n[0].value = "Hello";
...