Почему @array ~~ LIST возвращает false, даже если @array содержит те же элементы, что и LIST? - PullRequest
4 голосов
/ 25 февраля 2012

у меня

@a = (1,2,3); print (@a ~~ (1,2,3))

и

@a = (1,2,3); print (@a == (1,2,3))

Первый - тот, который я ожидаю работать, но он ничего не печатает. Второй печатает 1.

Почему? Разве умный оператор сопоставления ~~ не должен совпадать в случае @a ~~ (1,2,3)?

Ответы [ 3 ]

12 голосов
/ 25 февраля 2012

Давайте на секунду рассмотрим немного другое

\@a ~~ (1,2,3)

~~ оценивает свои аргументы в скалярном контексте, поэтому приведенное выше совпадает с

scalar(\@a) ~~ scalar(1,2,3)
  • \@a (в любом контексте) возвращает ссылку на @a.
  • 1, 2, 3 в скалярном контексте аналогичен do { 1; 2; 3 }, возвращая 3.

Так что минус пара предупреждений *, приведенное выше эквивалентно

\@a ~~ 3

То, что вы на самом деле хотите, это

\@a ~~ do { my @temp = (1,2,3); \@temp }

, которое можно сократить до

\@a ~~ [ 1,2,3 ]

Наконец, магия ~~ позволяет записать \@a как @a, так что его можно сократить до

@a ~~ [ 1,2,3 ]

* & mdash; Всегда используйте use strict; use warnings;!

9 голосов
/ 25 февраля 2012

Умное сопоставление пытается сделать то, что, как я думаю, вы ожидаете, если вы используете массив или ссылку на массив справа - но не список.

$ perl -E '@a = (1, 2, 3); say (@a ~~ (1, 2, 3))'

$ perl -E '@a = (1, 2, 3); say ((1, 2, 3) ~~ @a)' # also misguided, but different
1
$ perl -E '@a = (1, 2, 3); say (@a ~~ [1, 2, 3])'
1
6 голосов
/ 25 февраля 2012

Начните с В чем разница между списком и массивом? в perlfaq.В частности, он показывает, как неверно выбран ваш выбор значений.

Вы также можете начать с того, что напишите, почему вы ожидаете, что каждый из них будет работать или не работать, чтобы мы могли скорректировать ваши ожидания.Почему вы думали, что получите ожидаемые результаты?

Что касается битов умного совпадения, для ARRAY ~~ LIST нет никаких правил.Интеллектуальное совпадение работает только с парами, перечисленными в его таблице в perlsyn .Это заставит его быть одной из этих пар.

Когда вы столкнетесь с этими проблемами, попробуйте еще много случаев:

#!perl
use v5.10.1;
use strict;
use warnings;

my @a = (1,2,3);
say "\@a is @a";
say "\@a ~~ (1,2,3) is ", try( @a ~~ (1,2,3) );
say "\@a ~~ [1,2,3] is ", try( @a ~~ [1,2,3] );
say "\@a ~~ 3 is ", try( @a ~~ 3 );
say "3 ~~ \@a is ", try( 3 ~~ @a );

say '';

my @b = (4,5,6);
say "\@b is @b";
say "\@b ~~ (4,5,6) is ", try( @b ~~ (4,5,6) );
say "\@b ~~ [4,5,6] is ", try( @b ~~ [4,5,6] );
say "\@b ~~ 3 is ", try( @b ~~ 3 );
say "3 ~~ \@b is ", try( 3 ~~ @b );

say '';
say "\@b ~~ \@a is ", try( @b ~~ @a );

sub try { $_[0] || 0 }

Вывод различных случаев является подсказкой того, что вынеправильно прочитал документы:

Useless use of a constant (2) in void context at test.pl line 8.
Useless use of a constant (4) in void context at test.pl line 17.
Useless use of a constant (5) in void context at test.pl line 17.
@a is 1 2 3
@a ~~ (1,2,3) is 0
@a ~~ [1,2,3] is 1
@a ~~ 3 is 0
3 ~~ @a is 1

@b is 4 5 6
@b ~~ (4,5,6) is 0
@b ~~ [4,5,6] is 1
@b ~~ 3 is 0
3 ~~ @b is 0

@b ~~ @a is 0
...