2010-12-08 21 views
17

używam operatora ||= podać wartości domyślne dla zmiennych, jakDlaczego nie || = praca z tablicami?

$x ||= 1; 

Próbowałem użyć tej składni z tablicą ale dostałem błąd składni:

@array||= 1..3; 
Can't modify array dereference in logical or assignment (||=) ... 

Co to znaczy i jak powinienem zapewnić tablice z wartościami domyślnymi?

Odpowiedz

18

Ponieważ || jest operatorem skalarnym. Jeśli zadziałałby @array||= 1..3;, oceniłby on 1..3 w kontekście skalarnym, co nie jest tym, czego potrzebujesz. Ocenia także tablicę w kontekście skalarnym (co jest ok, ponieważ pusta tablica w kontekście skalarnym jest fałszywa), z tym że nie można przypisać do scalar(@array).

przypisać wartość domyślną, przeznaczenie:

@array = 1..3 unless @array; 

Należy jednak pamiętać, że nie ma sposobu, aby odróżnić tablicy, która nigdy nie została zainicjowana i jeden, który został przypisany pustą listę. Nie jest to skalar, w którym można odróżnić undef i pusty łańcuch (chociaż ||= nie rozróżnia między nimi).

eugene y znalazła się this perl.perl5.porters message (oficjalna lista mailingowa programistów Perla), która zawiera więcej szczegółów na ten temat.

+5

'||' nie jest skalarne operator chociaż narzuca kontekst skalarny na to lewy operand. Z Perlop: "Kontekst skalarny lub listowy propaguje się w dół do prawego argumentu, jeśli jest oceniany." 'perl -MData :: Dump = dump -e" @a = 0 || (1 .. 3); dump (\ @ a) "' drukuje '[1, 2, 3]' –

+0

* "nie ma sposobu, aby wskaż różnicę między tablicą, która nigdy nie została zainicjalizowana, a tą, która została przypisana pustą listą "* Różnica polega nie tylko na niemożności: * nie ma różnicy *. – Borodin

+0

Ta odpowiedź jest całkowicie błędna. 'perl -le'print 0 || 1..3'' wypisuje '123', a nie wydrukuje pustej linii, takiej jak' print skalar (1..3) '. – ikegami

16

Ten page ma dobre wytłumaczenie, imho:

op= can occur between any two expressions, not just a var and an expression, but the left one must be an lvalue in scalar context.

Since @x ||= 42 is equivalent to scalar(@x) = @x || 42 , and you aren't allowed to use scalar(@x) as an lvalue, you get an error.