In Perl hangt het resultaat van een toewijzing (en dus ook het werken met arrays en hashes) af van de context.
my @arr = (10, 20, 30); my $count = @arr; # $count == 3 my ($first, $second) = @arr; # $first == 10, $second == 20
Voor hashes:
my %h = (a=>1, b=>2, c=>3); my $size = %h; # $size == 3 in moderne versies van Perl, maar dat was vroeger niet zo!
Pas op voor het toewijzen van een link naar een array in plaats van het kopiëren van de inhoud!
Wat is het verschil tussen een array toewijzen aan een referentie en het kopiëren van de inhoud van een array?
Antwoord:
my @a = (1,2,3); my $ref = \@a; # $ref is een referentie naar de array, wijzigingen via $ref zijn zichtbaar in @a my @b = @a; # @b is een nieuwe array, wijzigingen in @b hebben geen invloed op @a # Vergelijk: push @$ref, 4; # @a is nu (1,2,3,4) push @b, 5; # @a blijft (1,2,3,4); @b is (1,2,3,5)
Verhaal 1
In een project werd een array doorgegeven aan een subroutine via een referentie, zonder te begrijpen dat het inderdaad een referentie was: de functie wijzigde deze op de plek van aanroepen. Er kwamen bugs binnen — in de aanroepende code was de datastructuur "bedorven". Er werd een kopie verwacht, maar er werd een alias ontvangen.
Verhaal 2
Een ingenieur rekende erop dat scalair toewijzing
%hhet werkelijke aantal paren zou retourneren. Blijkbaar — in oudere versies van Perl was dit gedrag anders: het retourneerde het aantal slots/bakken, niet de lengte! Uiteindelijk kwam er soms niet 3, maar een ander getal terug, wat de statistieken verstoorde.
Verhaal 3
In een grote ETL-systeem werden arrays gekopieerd via referenties, en daarna per ongeluk elkaars gegevens overschreven, omdat iedereen met dezelfde array werkte in plaats van met onafhankelijke kopieën. Het diagnoseren van de fout kostte enkele dagen.