2013-05-13 5 views
6

Мышление о следующем. Есть список

qw(a b c); 

теперь присвоить LIST в безымянный (анонимный) ARRAY

[ qw(a b c) ] 

поэтому следующего

use 5.016; 
use warnings; 
use diagnostics; 
my $x = [ qw(a b c) ]; 
say ref $x; #ARRAY - the $x is an ARRAY reference, and 
say $x->[1]; #prints "b", and 
say [ qw(a b c) ]->[1]; #works too 

но то, что происходит сейчас?

use 5.016; 
use warnings 'all'; 
use diagnostics; 
say ${[ qw(a b c) ]}[1]; 

печатает b, но

my $y = ${[ qw(a b c) ]}; 

ошибка,

Not a SCALAR reference at pepe line 6 (#1) 
    (F) Perl was trying to evaluate a reference to a scalar value, but found 
    a reference to something else instead. You can use the ref() function 
    to find out what kind of ref it really was. See perlref. 

Uncaught exception from user code: 
    Not a SCALAR reference at pepe line 17. 

Так, Что означает Contruction $ {....}

  • It «работает» в say (печатает второй элемент т анонимного массива), но не понимаю, почему
  • , но не может назначить его в переменную

И намек на diagnostics не очень полезно, потому что, как я должен использовать ref, когда я не может назначить? Что я пропустил от perlref?

ответ

10

${ EXPR1 }[ EXPR2 ] - это разыменование индекса массива. Он возвращает элемент в индексе, возвращаемом EXPR2 массива, на который ссылается ссылка, возвращаемая EXPR1.

${ $array_ref }[ ... ] - это ссылки на массивы как $array[...] - это массивы.


${ EXPR }, что не следует [ или { является скаляром разыменования. Он возвращает скаляр, на который ссылается ссылка, возвращаемая EXPR.

${ $scalar_ref } относится к скалярным ссылкам, так как $scalar относится к скалярам.


Как вы можете видеть, когда имеешь дело с ссылкой, вы можете использовать тот же синтаксис, как обычно, за исключением того, что вы замените имя переменных с {$ref} (сохраняя ведущую сигилу).

Таким образом, @{ $array_ref } - это ссылки на массивы как @array - это массивы.

say @{[ qw(a b c) ]}; 

Это суть диаграммы в моем предыдущем посте Mini-Tutorial: Dereferencing Syntax. Смотрите также:


К сожалению, я думал, что вы

say ${[ qw(a b c) ]}; # Want to print a b c 

Вы

my $y = ${[ qw(a b c) ]}; 

Вы хотите

my $y = [ qw(a b c) ]; 

[] создает массив и ссылку на этот массив и возвращает последний, вроде как

my $y = do { my @anon = qw(a b c); \@a }; 
+0

Обновлено ответа. – ikegami

+0

'$ {BLOCK} [EXPR]' – ysth

+0

@ysth, да, хотя вы имеете в виду '$ BLOCK [EXPR]'. Я настроюсь (используя что-то немного менее запутанное). – ikegami

4

Учитывая массив @arr и ссылку на массив $aref = \@arr, то внутри следующих групп выражений всех строки эквивалентны:

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

@ arr 
@{$aref} 

Доступ к скаляру в массиве:

$ arr [$i] 
${$aref}[$i] 
$ aref->[$i] 

Доступ кусочком записей:

@ arr [$i .. $j] 
@{$aref}[$i .. $j] 

(пробелы включены для выравнивания и не рекомендуются для фактического кода).

${}, @{} ... являются обходными операторами разыменования. Однако доступ к одному скаляру меняет сигил от % или @ до $. Без ссылок это делает полный смысл. С ними это немного сложно, пока вы не прочитаете perlreftut (особенно в двух правилах использования ссылок).

1

С

${$ar}[0] 

вы сказали Perl: $ar принять, как arrayref и вернуть мне 1-ый элемент из массива в то, что ссылка $ar точек.

С постройкой

${$sr} 

вы говорите PERL: взять $sr как SCALAR REF и возвращает значение скаляра к тому, что ссылка $sr точек.

Таким образом, ответ на ваш вопрос: Когда $ ar является массивом-ref, ЧТО ТАКОЕ $ {$ ar}? является:

Когда $ ар является $ массив ссылок, то $ {$ аг} являетсяОШИБКА,

, потому что вы сказали Perl - скалярно-реф, но $ ar не является scalar-ref (это arrayref).

Следующий пример показывает ваши конструкции ясно:

use 5.012; 
use warnings; 

my @arr = qw(a b c); 
my $aref = \@arr; 

my $myval = "VALUE"; 
my $sref = \$myval; 

say $aref->[0]; 
say ${$aref}[0]; 
say ${$sref}; #your construction - here CORRECTLY points to an scalar 

#say ${$aref} #ERROR because the ${$xxx} mean: take scalar ref, but the $aref is array ref. 
+0

oh shit. :(Теперь понимаю, что Perl ищет скалярную ссылку и нашел ссылку на массив - поэтому это ошибка. Я немного медленный, но получаю его ...;) – cajwine

Смежные вопросы