2013-01-21 10 views
6

Czy jest lepszy sposób to zrobić? Próbuję zbudować 2 tablice na podstawie wartości skalara:Warunkowo przesuń do 1 z 2 tablic w Perlu

my (@x, @y); 
my $r = [$v1, $v2, $v3]; 
push @x, $r if $s eq 'YES'; 
push @y, $r if $s ne 'YES'; 

Próbowałem za pomocą:

push $s eq 'YES' ? @x : @y, $r; 

i bez parens, ale nie udać.

Błąd jest:

Type of arg 1 to push must be array (not null operation) at comp_report.pl line 79, near "$r;" 
+0

Myślę, że Twój kod jest prawidłowy. Myślę, że używanie * operatora trójskładnikowego * do czegoś innego niż przypisywanie zmiennej jest złym nawykiem (co można zrobić z operatorem potrójnym Perla * czasami nie można go odtworzyć w innych językach implementujących go) –

Odpowiedz

13

Push wymaga swój pierwszy parametr do rzeczywistej tablicę (przynajmniej przed Perl 5.14, a wcześniej - może to być zmienione), a nie wyraz, więc trzeba:

push @{ $s eq 'YES' ? \@x : \@y}, $r; 

Począwszy od 5.14, builtins takie jak naciśnięcie experimentally can take arbitrary hard references, tak to działa:

push $s eq 'YES' ? \@x : \@y, $r; 
+0

+1 Zaledwie kilka sekund wcześniej niż ta sama odpowiedź [tutaj] (http://stackoverflow.com/a/14446203/1337398). :) – speakr

9
push @{ $s eq 'YES' ? \@x : \@y }, $r; 

push Naprawdę chce uzyskać tablicę jako pierwszy argument, ale nadal można dynamicznie wybrać obiekt docelowy za pomocą odniesień.

1

Moje preferowanym rozwiązaniem byłoby

if($s eq 'YES'){ 
    push @x, $r; 
else{ 
    push @y, $r; 
} 

Podobnie rzecz styl. Używanie potrójnego wyrażenia jako pierwszego argumentu dla pchania wygląda na bałagan dla mnie i nie mam nic przeciwko dodatkowym liniom. Osobisty smak, jak sądzę!

+0

Nie wdając się w to zbyt głęboko, posiadanie kontroli nad "l-wartościami" oraz "wartościami r" jest czymś, czego oczekuję od dynamicznego języka. Na przykład w Lisp jest to typowy idiom. Byłem zaskoczony, że Perl walczył ze mną w tej sprawie i naprawdę chciałem się dowiedzieć, czy to możliwe. – jeberle

Powiązane problemy