2011-12-09 28 views
14

Chcę utworzyć odwołanie do tablicy uzyskanej przez podział w Perlu. myślę coś takiego:Jak odwołać się do wyrażenia podzielonego w Perlu?

my $test = \split(/,/, 'a,b,c,d,e'); 

foreach $k (@$test) { 
    print "k is $k\n"; 
} 

Ale to narzeka Not an ARRAY reference at c:\temp\test.pl line 3. Próbowałem kilka innych alternatyw, wszystko bezskutecznie.

Odpowiedz

31

Tło wyjaśnienie:

split, podobnie jak inne funkcje, zwraca listę. Nie możesz odwołać się do listy. Jeśli jednak zastosujesz operator referencyjny do listy, zostanie on zastosowany do wszystkich jego członków. Na przykład:

use Data::Dumper; 

my @x = \('a' .. 'c'); 

print Dumper \@x 

wyjściowa:

$VAR1 = [ 
      \'a', 
      \'b', 
      \'c' 
     ];

Dlatego, kiedy piszesz my $test = \split(/,/, 'a,b,c,d,e');, masz odniesienie do ostatniego elementu zwróconej listy (patrz, na przykład, What’s the difference between a list and an array?). Twoja sytuacja jest podobna do:

Chociaż wygląda na to, że masz listę na prawej stronie, Perl faktycznie widzi kilka skalarów oddzielone przecinkiem:

my $scalar = ('dog', 'cat', 'bird'); # $scalar gets bird 

skoro "przypisanie do skalaru, prawa strona jest w kontekście skalarnym. Operator przecinka (tak, to operator!) W kontekście skalarnym ocenia swoją lewą stronę, odrzuca wynik i ocenia jego prawą stronę i zwraca wynik. W efekcie ta lista - przyporządkowuje do wartości $ skalar, która jest wartością najbardziej prawą. bałagan to wiele osób się becuase oni wybrać list-sobowtóra, którego ostatnim elementem jest również liczą się spodziewać:

my $scalar = (1, 2, 3); # $scalar gets 3, accidentally 

W twoim przypadku, to co masz na RHS jest lista odniesień do elementów lista zwrócona przez split, a ostatni element tej listy kończy się $test. Najpierw musisz zbudować tablicę z tych zwracanych wartości i odwołać się do tego. Można zrobić, że pojedyncza wypowiedź tworząc anonimowej tablicy i przechowywania odniesienie do tego w $test:

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

Dlatego właśnie uwielbiam SO! Bardzo dziękuję za dokładne, cierpliwe i bardzo jasne wyjaśnienie. Teraz jest całkowicie jasne, wiele się dzisiaj nauczyłem. Dzięki! –

19

Rozdzielenie split polecenia między nawiasami kwadratowymi w celu uzyskania anonimowego odniesienia.

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

Dzięki byłem nieco wprowadzać w błąd z przykładów ukośnik w mojej książce Perl. –

+1

Czy to jest tak skuteczne, jak przechowywanie wyniku podziału w var '@ splitResult', a następnie odwołanie do tego zestawu zmiennego za pomocą' $ arrayRef = \ @ splitResult'? Lub czy tablica jest inicjowana dwa razy? Raz podczas podziału i ponownie, aby zainicjować anonimową tablicę ref. – Despertar

Powiązane problemy