2009-09-08 8 views
7
#!/usr/bin/perl 

use strict; 
use warnings; 

my @a = qw/a b c/; 
(@a) x= 3; 
print join(", ", @a), "\n"; 

spodziewałbym powyższy kod, aby wydrukować "a, b, c, a, b, c, a, b, c\n", lecz umiera z komunikatem:Dlaczego pojawia się błąd podczas próby użycia operatora przypisania gadów z tablicą?

Can't modify private array in repeat (x) at z.pl line 7, near "3;" 

To wydaje się dziwne, ponieważ X <op>= Y są udokumentowane za równoważne X = X <op> Y i Następujący kod działa jak Spodziewam się, że:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @a = qw/a b c/; 
(@a) = (@a) x 3; 
print join(", ", @a), "\n"; 

Czy jest to błąd w Perlu, czy też nie rozumiem, co powinno się tutaj wydarzyć?

Odpowiedz

0

Problem polega na tym, że próbujesz zmodyfikować @ na miejscu, czego Perl najwyraźniej nie pozwala ci zrobić. Twój drugi przykład robi coś subtelnie innego, czyli tworzy nową tablicę składającą się z trzykrotnego powtórzenia, a następnie nadpisywania @a tą wartością.

Prawdopodobnie pierwsza forma powinna być przejrzyście tłumaczona na drugiej postaci, ale to nie jest to, co rzeczywiście się dzieje. Możesz uznać to za błąd ... umieść go w odpowiednich miejscach i zobacz, co się stanie.

1

Zgaduję, że Perl nie jest językiem z pełnymi symbolicznymi przekształceniami. Próbuje dowiedzieć się, co masz na myśli. Jeśli "list-ify" @a, przez umieszczenie go w parens, to rodzaj traci to, co chcesz mu przypisać.

Zauważ, że to nie to, co chcemy:

my @b = @a x 3; # we'll get scalar(@a) --> '3' x 3 --> '333' 

Ale to robi:

my @b = (@a) x 3; 

Jak robi:

(@a) = (@a) x 3; 

Wydaje się więc, że gdy ekspresja pojawia się po obu stronach Perla interpretuje je w różnych kontekstach. Wie, że coś przypisujemy, więc próbuje dowiedzieć się, do czego przypisujemy.

Powiedziałbym to do błędu, z bardzo rzadko używanej składni.

+0

Tak, tylko ja wpadłem na niego, bo jestem dokumentowania wszystkich operatorów (github.com/cowens/perlopref) i testował moje naiwne założenie, co należy zrobić. –

+1

Nie sądzę, bym to nazwał błędem, ponieważ podręcznik Perla 4 wyraźnie wspomina, że ​​działa tylko na skalarach: http://www.cs.cmu.edu/afs/cs.cmu.edu/Web/People/rgs/pl-exp-op.html # x – mercator

+0

@mercator To nie jest podręcznik Perla (który będzie albo Wielbłądem, albo czymś dostępnym z 'perldoc'). Fakt, że dokumentuje to samo zachowanie, nie oznacza, że ​​zachowanie nie jest błędem. Zobacz http://perldoc.perl.org/perlop.html#Assignment-Operators dla aktualnej (5.10.1) dokumentacji. –

4

Moją pierwszą myślą było to, że było to niezrozumienie jakiejś subtelności w części Perla, a mianowicie, że pareny wokół @a sprawiły, że parsowanie było próbą przypisania do listy. (. Sama lista, lista nie jest normalne przypisanie) Stwierdzenie to wydaje się być wspierane przez perldiag:

Can't modify %s in %s

(F) You aren't allowed to assign to the item indicated, or otherwise try to change it, such as with an auto-increment.

Najwyraźniej nie jest to przypadek, choć. Gdyby było to powinny mieć ten sam błąd:

($x) x= 3; # ok 

Więcej niezbicie, daje ten sam błąd:

@a x= 3; # Can't modify private array in repeat... 

Ergo, na pewno błąd. Złóż to.

Powiązane problemy