Разыменование 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
и его подражание под строгим.
Ничего, что ты сделал, не требует 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[...].
Большинство людей даже не знают, что вы можете использовать их вне строковых литералов.