ProgrammationDéveloppeur Backend

Décrivez les différences entre la copie profonde et la copie superficielle des structures de données complexes en Perl. Comment garantir l'absence de liaisons indésirables entre les copies ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Perl, lors de la copie de structures de données complexes (par exemple, des tableaux de tableaux, des hachages de hachages), il est important de comprendre la différence entre "copie superficielle" (shallow copy) et "copie profonde" (deep copy).

La copie superficielle crée un nouveau conteneur (par exemple, un tableau ou un hachage), mais les éléments en seront référencés aux mêmes objets que l'original. Cela peut entraîner un comportement inattendu : modifier des données dans la copie affectera l'original.

La copie profonde crée une structure complètement indépendante, en copiant récursivement tous les éléments imbriqués. Pour la copie profonde en Perl, on utilise souvent le module Storable ou [Clone]:

use Storable 'dclone'; my $original = { a => [1, 2, { b => 3 }] }; my $copy = $original; # Copie superficielle my $deep = dclone($original); # Copie profonde $copy->{a}[2]{b} = 42; # Change à la fois $copy et $original ! $deep->{a}[2]{b} = 99; # Change seulement $deep

La copie profonde garantit que les structures sont complètement isolées les unes des autres.

Question piège

Quelle est la différence entre copier un tableau par l'affectation d'une variable et copier un tableau par référence ? Comment bien copier un tableau pour que les modifications dans l'un n'affectent pas l'autre ?

On répond souvent qu'il suffit d'affecter une référence : $copy = \@arr; — cependant, cela est faux, car les deux variables pointent vers le même tableau. Pour une copie indépendante, on utilise :

my @copy = @original; # Maintenant, les tableaux sont indépendants

Si des structures imbriquées doivent être copiées, une copie profonde est nécessaire, par exemple via Storable::dclone.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans un projet de parsing de grands fichiers XML, pour chaque document, un modèle de hachage avec des structures modèles était pris et copié par référence. Les modifications dans un document commençaient à affecter les autres, ce qui entraînait des bogues mystérieux avec des données "disparaissant" ou "décalées".

Histoire

Lors de l'authentification pour stocker des sessions, un tableau avec des hachages d'utilisateurs était utilisé. En recréant le tableau pour une nouvelle liste d'utilisateurs, seules les références étaient copiées, ce qui entraînait une "fuite" de données des utilisateurs de la session précédente.

Histoire

Lors de la mise en œuvre de modèles d'e-mails pour des envois de masse, les structures d'origine avec des objets imbriqués étaient copiées par affectation, les modifications dans le texte du modèle "fugaient" entre les envois, ce qui entraînait l'envoi de messages obsolètes aux destinataires.