Разыменование Perl в нестрогом режиме

В Perl, если у меня есть:

no strict;
@ARY = (58, 90);

Чтобы оперировать с элементом массива, скажем, вторым, я бы написал (возможно, как часть более крупного выражения):

$ARY[1]  # The most common way found in Perldoc's idioms.

Хотя, по некоторым причинам они также работают:

@ARY[1]
@{ARY[1]}

В результате все в одном объекте:

print (\$ARY[1]);
print (\@ARY[1]);
print (\@{ARY[1]});

Выход:

SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)

Каковы правила синтаксиса, которые разрешают этот вид конструкций? Как далеко можно придумать надежный программный код с каждой из этих конструкций или со всеми их сочетаниями? Насколько взаимозаменяемы эти выражения? (всегда говорить в нестрогом контексте).

Что касается обоснования того, как я вхожу в этот вопрос, я согласен "использовать строгий" как лучшую практику, но все же меня интересуют некоторые знания о построении нестрогих выражений.

В попытке найти себе какую-то помощь в этом беспокойстве, я пришел к:

  • Понятие "нет строгих"; не жаловаться на необъявленные переменные и причудливый синтаксис.
  • Разыменование префикса, имеющего более высокий приоритет, чем subindex [] (perldsc § "Предостережение по приоритету").
  • Разъяснение того, когда использовать @ вместо $ (perldata § "Slices").
  • Отсутствие описания "[]" (индекс / срез массива) среди операторов Perl (perlop), из-за которого я думаю, что это не оператор… (но это должно быть что-то еще. Но что?).

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

Заранее спасибо.

4 ответа

Решение

Цитата из perlfaq4:

В чем разница между $array[1] а также @array[1]?

Разница заключается в символе, специальном символе перед именем массива. $ Сигил означает "ровно один предмет", тогда как @ Сигил означает "ноль или более предметов". $ получает один скаляр, а @ получает вам список.

Пожалуйста, смотрите: В чем разница между $array[1] и @array[1]?

@ARY[1] это действительно кусочек, фактически кусочек только одного члена. Разница в том, что он создает контекст списка:

@ar1[0] = qw( a b c );    # List context.
$ar2[0] = qw( a b c );    # Scalar context, the last value is returned.
print "<@ar1> <@ar2>\n";

Выход:

<a> <c>

Помимо использования strict, очередь warnings на тоже. Вы получите следующее предупреждение:

Scalar value @ar1[0] better written as $ar1[0]

В perlop вы можете прочитать, что "операторы разыменования префиксов Perl набираются: $, @, % и &". Стандартный синтаксис SIGIL { ... }, но в простых случаях фигурные скобки могут быть опущены.

См. Можно ли использовать строку в качестве ссылки HASH, когда используются "строгие ссылки"? чтобы повеселиться с no strict refs и его подражание под строгим.

Расширяя ответ Чоробы, чтобы проверить конкретный контекст, вы можете использовать wantarray

sub context { return wantarray ? "LIST" : "SCALAR" }

print $ary1[0] = context(), "\n";
print @ary1[0] = context(), "\n";

Выходы:

SCALAR
LIST

Ничего, что ты сделал, не требует no strict; кроме как скрыть свою ошибку

@ARY = (58, 90);

когда ты должен был сделать

my @ARY = (58, 90);

Следующее возвращает один элемент массива. поскольку EXPR возвращает единственный индекс, он оценивается в скалярном контексте.

$array[EXPR]

например

my @array = qw( a b c d );
my $index = 2;
my $ele = $array[$index];   # my $ele = 'c';

Следующее возвращает элементы, идентифицированные как LIST, поскольку LIST должен вернуть 0 или более элементов, это должно быть оценено в контексте списка.

@array[LIST]

например

my @array = qw( a b c d );
my @indexes ( 1, 2 );
my @slice = $array[@indexes];   # my @slice = qw( b c );

\( $ARY[$index]   )  # Returns a ref to the element returned by $ARY[$index]
\( @ARY[@indexes] )  # Returns refs to each element returned by @ARY[@indexes]

${foo}       # Weird way of writing $foo. Useful in literals, e.g. "${foo}bar"
@{foo}       # Weird way of writing @foo. Useful in literals, e.g. "@{foo}bar"
${foo}[...]  # Weird way of writing $foo[...].

Большинство людей даже не знают, что вы можете использовать их вне строковых литералов.

Другие вопросы по тегам