7
votes

Y a-t-il un meilleur moyen de passer par référence à Perl?

Je fais de la transmission-référence comme ceci:

use strict;
use warnings;

sub repl {
    local *line = \$_[0]; our $line;
    $line = "new value";
}

sub doRepl {
    my ($replFunc) = @_;
    my $foo = "old value";
    $replFunc->($foo);
    print $foo; # prints "new value";
}

doRepl(\&repl);


0 commentaires

4 Réponses :


3
votes

Il y a quelques façons de le faire. Passer explicitement une referflate Ref to $ FOO CODE> ou profitez de la passe intégrée de Perl par la sémantique de référence.

Référence explicite: P>

sub repl {
    for my $line( $_[0] ) {
        $line = 'new value';
    }
}


0 commentaires

9
votes

Avez-vous regardé Data :: Alias ​​? Il vous permet de créer des alias de manière lexicalement avec une syntaxe propre.

Vous pouvez l'utiliser pour créer une sémantique de transmission par référence comme ceci: xxx

la sortie est < Code> 1 , indiquant que l'appel à foo a modifié son argument.


3 commentaires

Malheureusement, j'ai examiné la section "Mise en œuvre" des docs ... ACK! Je suppose que ce module est un peu comme des saucisses ... beaucoup plus agréables si vous ne savez pas comment ils sont faits ... :)


@Joelfan: Yup. C'est beaucoup un module "N'essayez pas à la maison" :)


Démarre "Ce module n'utilise pas de filtre source" et descend de là ... :)



3
votes

sub repl {
    my $line = \$_[0];     # or: my $line = \shift
    $$line = "new value";
}


3 commentaires

@Sinan - n'aurait pas deviné que cela fonctionnerait. Apprendre quelque chose de nouveau chaque jour.


Règle voir perdoc.perl.org/perlref.html#making-riférences " En tant que cas particulier, \ (@ foo) renvoie une liste de références au contenu de @foo , pas une référence à @foo elle-même . "


Dans contexte scalaire, \ (@ foo) est une référence à une valeur scalaire contenant le nombre d'éléments dans @foo [c'est-à-dire, comme \ (scalaire @ foo) ]



0
votes

Je ne pense pas qu'il n'y ait rien de mal à utiliser local pour créer l'alias dans ce cas.

La portée dynamique est bien sûr une caractéristique puissante, mais aussi longtemps que vous êtes au courant des effets secondaires (la nouvelle valeur est visible dans des fonctions appelées de son champ d'application, si un lexical du même nom est en portée, il ne peut pas Soyez localisé, ...) Ensuite, il s'agit d'un ajout utile à la boîte à outils PERL déjà débordante.

La raison principale des avertissements dans les documents Perl sur local est de garder les gens à l'utiliser par inadvertance au lieu de mon et de faciliter la transition de Perl4. Mais il y a définitivement des moments où local est utile, ce qui en est un.

Utiliser pour Pour créer votre alias est également une option, mais je trouve la syntaxe explicite avec local plus clairement dans son intention. Il est également un peu plus rapide si la performance est une préoccupation.


0 commentaires