2013-05-28 7 views
6

Mam podprogram, który zwraca skrót. Ostatnie wiersze podprogramu:Podprogram, który zwraca skrót - dzieli go na oddzielne zmienne.

print Dumper(\%fileDetails); 
return %fileDetails; 

w tym przypadku wydruki samowyładowcze:

$VAR1 = { 
      'somthing' => 0, 
      'somthingelse' => 7.68016712043654, 
      'else' => 'burst' 
} 

Ale gdy próbuję zrzucić go wywołaniu podprogramu z tej linii:

print Dumper(\fileDetailsSub($files[$i])); 

dumper wydruki:

$VAR1 = \'somthing'; 
$VAR2 = \0; 
$VAR3 = \'somthingelse'; 
$VAR4 = \7.68016712043654; 
$VAR5 = \'else'; 
$VAR6 = \'burst'; 

WŁ ce hash jest zepsute, nie mogę go już używać. Dlaczego tak się dzieje? I w jaki sposób mogę zachować właściwą strukturę po powrocie podprogramu?

Dzięki, Mark.

+0

Odpowiedź brzmi: "\\", które mechanicznie wstawiasz do wywołań Dumper() :-) –

Odpowiedz

9

Nie ma czegoś takiego jak zwrot haszu w Perlu.

Podprogramy wziąć list jak ich argumentów i mogą wrócić list ich wyniku. Zauważ, że lista jest bardzo różnym stworzeniem z tablicy.

Kiedy piszesz

return %fileDetails; 

Jest to odpowiednik:

return ('something', 0, 'somethingelse', 7.68016712043654, 'else', 'burst'); 

Po wywołaniu podprogramu i dostać tę listę z powrotem, jedno można zrobić, to przypisać go do nowego hash:

my %result = fileDetailsSub(); 

To działa, ponieważ hash można zainicjować z listy par klucz-wartość. (Pamiętaj, że (foo => 42, bar => 43) to samo, co ('foo', 42, 'bar', 43).

Teraz, kiedy użyć operatora referencji backslash na hash, jak w \%fileDetails, masz odniesienie hash który jest skalarne punkty do mieszania.

Podobnie, jeśli piszesz \@array, masz odniesienie do tablicy.

Ale kiedy użyć operatora referencji na listy, nie dostaniesz odniesienie do wykazu (od wykazy nie są zmiennymi (są efemeryczne), nie można ich przywoływać). Zamiast tego operator odniesienia dystrybuuje ponad elementów listy, więc

\('foo', 'bar', 'baz'); 

sprawia, że ​​nowa lista:

(\'foo', \'bar', \'baz'); 

(W tym przypadku możemy uzyskać pełną listę referencji skalarnych.) A to, co widzisz przy próbie uzyskania Dumper wyników podprogramu: operator referencyjny rozłożony na liście pozycji zwróconych z sub.

Jednym z rozwiązań jest przypisanie listy wyników do faktycznej zmiennej hash przed użyciem Dumper.Innym jest powrót odniesienie hash (czego Dumpering tak) z sub:

return \%fileDetails; 

... 

my $details_ref = fileDetailsSub(); 
print Dumper($details_ref); 

# access it like this: 
my $elem = $details_ref->{something}; 
my %copy = %{ $details_ref }; 

więcej zabawy, patrz:

8

Zamiast tego należy zamiast tego powrócić do skrótu do skrótu?

return \%fileDetails; 

Dopóki jest to zmienna leksykalny, nie będzie komplikować innych zastosowań podprogramu. Np .:

sub fileDetails { 
    my %fileDetails; 
    ... # assign stuff 
    return \%fileDetails; 
} 

Gdy wykonanie wychodzi z podprogramu, zmienna wychodzi poza zakres, ale dane zawarte w pamięci pozostają.

Powód, dla którego wyjście Dumper wygląda, polega na tym, że podajesz mu listę odniesienia. Podprogramy nie mogą zwracać tablic ani skrótów, mogą tylko zwracać listy skalarów. To, co robisz, jest mniej więcej takie:

print Dumper \(qw(something 0 somethingelse 7.123 else burst)); 
0

W kontekście listowym, Perl nie rozróżnia między hash a listą par klucz/wartość. Oznacza to, że jeśli podprogram return jest hash, to naprawdę zwraca listę (key1, value1, key2, value2...). Na szczęście działa to w obie strony; jeśli wziąć taką listę i przypisać go do mieszania, można uzyskać wierną kopię oryginału:

my %fileDetailsCopy = subroutineName(); 

Ale jeśli nie złamie inny kod, to prawdopodobnie więcej sensu mieć zwrot sub zamiast tego odniesienie do skrótu, jak powiedział TLP.

1

Nie można bezpośrednio zwrócić skrótu, ale perl może automatycznie konwertować między hashami i listami w razie potrzeby. Więc perl zamienia to na listę, a przechwytujesz ją jako listę. tj.

Dumper(filedetail()) # list 
my %fd = filedetail(); Dumper(\%fd); #hash 
3

Funkcje Perla nie mogą zwracać skrótów, a jedynie listy. Instrukcja return %foo spowoduje spłaszczenie %foo na liście i zwróci spłaszczoną listę.Aby uzyskać wartości zwracanej należy interpretować jako hash, można przypisać do określonego hash

%new_hash = fileDetailsSub(...); 
print Dumper(\%new_hash); 

lub cast it (nie wiem, czy to jest najlepsze słowo dla niego) z %{{...}} sekwencji operacji:

print Dumper(\%{ {fileDetailsSub(...)} }); 

Innym podejściem, jak wskazuje TLP, jest zwrócenie referencji hash z twojej funkcji.

Powiązane problemy