web-dev-qa-db-fra.com

Utilisation de défini/undef en Perl

Je prévois de transmettre deux variables à une fonction Perl, l'une d'elles pouvant être facultative. J'essaie de vérifier si le second est défini ou non, mais cela ne fonctionne pas correctement. Lorsque j'ai appelé la fonction en tant que myFunction (18), cela suppose que la variable $ optional est définie et passe à l'instruction else. Mais dans l'instruction else, lors de l'accès à la variable facultative $, une erreur "non initialisée" est générée. C’est exactement le contraire de ce que j’attendais. Toute aide est grandement appréciée.

sub myFunction {
  my ($length, $optional) = (@_);
  if(undef($optional)
  {
    more code..
  }
  else
  {
    more code...
  }
}

myFunction(18)
12
user466663

La fonction correcte est defined. undef undefines $optional. Ce que vous voulez faire est quelque chose comme ça:

sub myFunction {
    my( $length, $optional ) = @_;
    if( ! defined $optional ) {
        # Do whatever needs to be done if $optional isn't defined.
    }
    else {
        # Do whatever can be done if $optional *is* defined.
    }
}

Une autre façon de le gérer (en particulier Perl 5.10+) consiste à utiliser l'opérateur "défini ou", //, comme ceci:

sub MyFunc {
    my $length = shift;
    my $optional = shift // 'Default Value';
    # Do your stuff here.
}

Cela permet de détecter si la valeur de retour de shift @_ est définie. Comme vous avez déjà appelé shift une fois, nous testons maintenant le deuxième paramètre. S'il est défini, attribuez la valeur à $optional. S'il n'est pas défini, affectez 'Default Value' à $optional. Bien sûr, vous devez définir votre propre valeur par défaut.

Si vous êtes coincé dans les époques sombres de la pré-Perl 5.10, vous pouvez accomplir la même chose avec:

my $optional = shift;
$optional = defined $optional ? $optional : 'Default value';

...ou...

my $length = shift;
my $optional = defined( $_[0] ) ? shift : 'Default value';

Quoi qu'il en soit, je préfère souvent avoir un défaut sain, plutôt qu'un chemin de flux de contrôle totalement séparé. C'est souvent un bon moyen de simplifier le code.

22
DavidO
my $optional = defined( $_[0] ) ? shift : 'Default value';

C'est un code dangereux, car il ne modifie le paramètre que s'il est défini. Si vous aviez un troisième paramètre, cela serait confus lorsque vous appelez. 

MyFunc( 10, undef, 20 )
0
Binary Ben