2012-02-16 18 views
12

Przypisanie lista w kontekście skalarnym zwraca liczbę elementów na prawej stronie:Lista Obsadzenie w kontekście skalarnym

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2 

Dlaczego ocenić prawą stronę i produkować 2 zamiast nowo zdefiniowanej listy oceniając i zwracając 3?

Dla mnie wydaje się $hello dostaje 7, $there dostaje 8, a $world dostaje undef, to lista jest oceniana w kontekście skalarnym, co doprowadziłoby do 3, jako że jest to liczba elementów na liście ($hello $there $world). Wydaje się dziwne mi się, że kontekst wpływa która jest zwracana część ocenianego wypowiedzi:

my $greeting = (($hello, $there, $world) = (7,8)); #2 

my @greeting = (($hello, $there, $world) = (7,8)); 
my $greeting_length = @greeting; #3 
+1

Rzeczywiście, nie: Jeśli lista po lewej stronie była rzeczą ocenianą w kontekście skalarnym, wartość byłaby "undef". Lista nie jest tablicą. – darch

+0

@darch, To nie ma sensu. '($ hello, $ there, $ world)' (i '(7,8)') nie może być wykonane w kontekście skalarnym w '($ hello, $ there, $ world) = (7,8)'. Przypisanie listy może zwrócić 3, jeśli chce, ale nie ma powodu do tego. – ikegami

+0

Odpowiadałem właśnie na wyrażenie "wtedy [lista (cześć, tam $, świat $)] jest oceniana w kontekście skalarnym". Oceń 'my ($ h, $ t, $ w) = (7, 8, undef); skalar ($ h, $ t, $ w) 'i zobacz, że listy nie są tablicami. – darch

Odpowiedz

14

Jest udokumentowane policzyć elementy po prawej perlop (ostatnie zdanie w rozdziale operatory przypisania):

Podobnie, przypisanie list w kontekście listowym tworzy listę wartości l przypisanych do, a przypisanie listy w kontekście skalarnym zwraca liczbę elementów utworzonych przez wyrażenie po prawej stronie przypisania.

Powodem działa jak to jest tak, że można pisać takie rzeczy:

while (my ($key, $value) = each %hash) { ... } 

Jeśli liczy się liczbę elementów na lewej stronie przypisania, która byłaby nieskończona pętla.

Jeśli myślisz o tym, liczba elementów po lewej stronie jest taka sama jak po prawej stronie lub jest stała (gdy przypisujesz do listy skalarów). W pierwszym przypadku nie ma znaczenia, która strona się liczy, aw drugim przypadku bardziej przydatne jest zliczanie prawej strony.

Z drugiej strony, w kontekście listy operator przypisania zwraca listę lewej ręki, ponieważ jest to bardziej przydatne. Jeśli używasz go w kontekście, który modyfikuje elementy listy, chcesz zmodyfikować zmienne, które zostały właśnie przypisane.

Re: Twój komentarz W przykładzie (7,8) jest lista dwuelementowa, dlatego operator przypisania zwraca 2. Po przypisaniu krótszą listę do dłuższej listy skalarów, prawa strona nie jest "wyściełane" z undef przed wykonaniem zadania. Zamiast tego wszelkie zmienne, które nie mają wartości skojarzonej z nimi z listy po prawej stronie, zostaną zresetowane do wartości domyślnej. W przypadku zmiennej skalarnej jest to undef. W przypadku tablic jest to pusta tablica. W przypadku skrótów jest to pusty hasz.

+0

Twoja odpowiedź ma sens, rozumiem, dlaczego działa w ten sposób, ale bardziej interesuje mnie, jak to działa. Zobacz mój komentarz do posta na ikegamis. – Brian

+0

@Brian, w kontekście listowym, otrzymujesz listę lewej ręki, ale w kontekście skalarnym uzyskujesz liczbę list z prawej strony. W obu przypadkach jest to najbardziej przydatna rzecz do zwrócenia. Zobacz moją zaktualizowaną odpowiedź, by poznać szczegóły. – cjm

+0

@Brian, istnieje wiele funkcji i operatorów w Perlu, które w kontekście skalarnym zwracają coś innego niż liczbę elementów, które powrócą w kontekście listowym. Musisz przeczytać dokumenty, aby dowiedzieć się, co funkcja lub operator powróci. – cjm

6
Wydaje mi się, że dziwne efekty kontekstowe, która strona jest uwzględniany:

nie. Obie strony (operandy) operatora przypisania listy, a także to, czy przypisanie listy jest oceniane w kontekście skalarnym lub w kontekście listy, nie ma wpływu na ocenę operandów.

To, czy przypisanie listy jest obliczane w kontekście skalarnym, czy w kontekście listy wpływa tylko na wartość, którą zwraca.

Poprzednio stworzyłem Mini-Tutorial: Scalar vs List Assignment Operator, który próbuje wyjaśnić różnice między dwoma operatorami przypisania i ich zachowaniem w kontekście skalarnym i listowym.

+0

Edytowałem to zdanie, aby trochę wyjaśnić: "Wydaje mi się dziwne, że kontekst wpływa na to, która część ocenianego wyrażenia jest zwracana:" Wiem, że kontekst nie wpływa na ocenę i tylko wynik powrotu, ale chcę wiedzieć jak to działa. Jeśli prawa strona przypisania jest oceniana, a następnie przypisana do lewej strony, dlaczego skalar miałby otrzymać 2? Prawa strona przejdzie do listy 3 elementów, która następnie powinna zostać przypisana do skalaru. To tak, jakby perl po prostu zdecydował się zignorować reguły pierwszeństwa i wybrać, która część wyrażenia ma zostać zwrócona. – Brian

+0

O ile, oczywiście, 'my @greeting = (($ hello, $ there, $ world) = (7,8))' dałoby '@ greeting'' (7,8) 'zamiast' (hello, $ there, $ world) ', teraz miałoby to dla mnie większy sens. Ale jeśli '@ greeting' dostaje' ($ hello, $ there, $ world) 'i' $ greeting' otrzymuje wynik '(7,8)', to nie ma sensu. – Brian

+0

'$ greeting' nie otrzymuje wyniku' (7,8) '. W rzeczywistości '$ pozdrowienie' nie może uzyskać wyniku tego' (7,8) ', ponieważ to' (7,8) 'jest wartością listy, a wartości listy nie można przypisać do skalaru. Zarówno '@ greeting' i' $ greeting' uzyskują wynik przypisania listy, który jest albo "listą wartości ocenianych przez LHS", albo "liczbami elementów, których oceniano przez RHS" w zależności od kontekstu. Wydaje się, że sugerujesz, że lepiej byłoby zwrócić coś innego, nie podając żadnego powodu, w jaki sposób inne wyniki byłyby użyteczne. – ikegami

Powiązane problemy