Неожиданное хэширование - PullRequest
0 голосов
/ 21 мая 2018

Я ищу объяснение, почему эти две структуры данных не равны:

$ perl6 -e 'use Test; is-deeply [ { a => "b" } ], [ { a => "b" }, ];'
not ok 1 -
# Failed test at -e line 1
# expected: $[{:a("b")},]
#      got: $[:a("b")]

Завершающая запятая в хэшах и массивах бессмысленна, как в P5:

$ perl6 -e '[ 1 ].elems.say; [ 1, ].elems.say'
1
1

Нобез него хэш каким-то образом теряется, и он сводится к массиву пар:

$ perl6 -e '[ { a => "b", c => "d" } ].elems.say;'
2

Я подозреваю, что здесь применяются некоторые законы о рефакторинге Большого списка, но я хотел бы получить более подробное объяснение, чтобы понять логику этого выравнивания.

1 Ответ

0 голосов
/ 21 мая 2018

Запятая в хэшах и массивах не имеет смысла, как в P5

Нет, это не бессмысленно:

(1 ).WHAT.say ; # (Int)
(1,).WHAT.say ; # (List)

Большое упрощение вGreat List Refactor переключался на правило единственного аргумента для итерации объектов 1 .То есть такие функции, как for или составители массива и хеша (и индексы) всегда получают один аргумент.Это действительно то, что происходит с вашим оригинальным примером.

Единственным аргументом может быть - часто будет - список значений, возможно, даже список списков и т. Д., Но список верхнего уровня все равно будет единственным аргументом функции итерации.

Если один аргумент итеративного объекта выполняет роль Итерируемый (например, списки, массивы и хэши), то он повторяется.(Это неточная формулировка; см. мой ответ на «Когда вызывать метод итератора?» Для более точного ответа.)

Так что ключевая вещь, которую следует отметить здесь об этой дополнительнойзапятая в том, что если один аргумент не выполняет роль Iterable, такую ​​как 1, то конечный результат точно такой же, как если бы аргумент был вместо этого списком, содержащим только это одно значение (то есть 1,):

.perl.say for {:a("b")}   ; # :a("b")     Iterable Hash was iterated
.perl.say for {:a("b")} , ; # {:a("b")}   Iterable List was iterated
.perl.say for 1           ; # 1           Non Iterable 1 left as is
.perl.say for 1 ,         ; # 1           Iterable List was iterated

Типичный способ «сохранить структуру [кроме], используя запятую, когда объявлен список из одного элемента» (см. комментарий ниже), то есть stop значение Iterable, повторяемое как обычно, составляет item , изменяющее его на $:

my @t = [ $[ $[ "a" ] ] ];
@t.push: "b";
@t.perl.say; # [[["a"],], "b"]

1 Итерацияиспользуется для получения значений для передачи в некоторый код в случае for;получить значения, которые станут элементами массива / хэша, создаваемого в случае композитора;получить индексный фрагмент в случае нижнего индекса;и так далее для других итерационных функций.

...