Funktion defined() i Perl

I programmeringssproget Perl har en indbygget funktion defined().

Oftest er denne funktion bruges til at skelne værdien undef fra enhver anden værdi. Men selv med hjælp af defined() , kan du finde ud af, om du har defineret en funktion.

Check undef

Vigtigste anvende funktionen defined() er en check på værdien undef.

Hvis overførslen funktion defined() værdi undef, vil funktionen returnere false. Funktionen vil returnere "true", hvis den værdi, som det overføres der er noget, men undef. Her er et eksempel kode:

▶ Run
#!/usr/bin/perl

use Data::Dumper;

print Dumper defined(8);
print Dumper defined(0);
print Dumper defined('');
print Dumper defined(undef);

Resultatet af denne kode:

$VAR1 = 1;
$VAR1 = 1;
$VAR1 = 1;
$VAR1 = '';

Check, at funktionen er defineret

Oftest, funktion defined() er anvendt for at skelne undef fra en anden værdi. Men udover at bruge defined() kan du lære, om du har defineret en funktion. Her er et eksempel kode:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

print Dumper defined(&check);
print Dumper defined(&Data::Dumper::Dumper);

Funktion check() er ikke defineret, så defined() returnerer falsk, Men funktionen Dumper et bundt Data::Dumper og defined() return 'true'. Det er, hvad dette program vises på skærmen:

$VAR1 = '';
$VAR1 = 1;

Argumenter

Hvis funktionen defined() ikke gives ingen argumenter, den fungerer med standard variable $_:

Hvis overførslen funktion defined() mere end ét argument, vil det være en fejl, og udførelsen af et program vil blive stoppet:

Too many arguments for defined operator at script.pl line 3, near "3)"
Execution of script.pl aborted due to compilation errors.

Return værdi

Resultatet af funktionen defined() altid er en Boolesk værdi. Sandt eller falsk.

Brug med en vifte, og Hesham

Meget lang funktion defined() arbejdede på en særlig måde, hvis du fortæller hende det en matrix eller hash som argument. Men i Perl 5.8 denne bruger der er udstedt en advarsel, og da 5.22 denne brug begyndte at svigte.

Her er et eksempel kode, som i defined() er bestået et array:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @arr;

print Dumper defined(@arr);

Resultatet af denne kode i perl version 5.8:

defined(@array) is deprecated at script.pl line 10.
    (Maybe you should just omit the defined()?)
    $VAR1 = '';

Resultatet af dette, når 5.30 perl:

Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at script.pl line 10.

Og den samme kode, men om hash:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %h;

print Dumper defined(%h);

Resultaterne af arbejdet med perl 5.8 og 5.30:

defined(%hash) is deprecated at script.pl line 10.
    (Maybe you should just omit the defined()?)
    $VAR1 = '';
Can't use 'defined(%hash)' (Maybe you should just omit the defined()?) at script.pl line 10.

Officiel dokumentation

Her er outputtet af kommandoen perldoc -f defined:

       defined EXPR
       defined Returns a Boolean value telling whether EXPR has a value other
               than the undefined value "undef".  If EXPR is not present, $_
               is checked.

               Many operations return "undef" to indicate failure, end of
               file, system error, uninitialized variable, and other
               exceptional conditions.  This function allows you to
               distinguish "undef" from other values.  (A simple Boolean test
               will not distinguish among "undef", zero, the empty string, and
               "0", which are all equally false.)  Note that since "undef" is
               a valid scalar, its presence doesn't necessarily indicate an
               exceptional condition: "pop" returns "undef" when its argument
               is an empty array, or when the element to return happens to be
               "undef".

               You may also use "defined(&func)" to check whether subroutine
               &func has ever been defined.  The return value is unaffected by
               any forward declarations of &func.  A subroutine that is not
               defined may still be callable: its package may have an
               "AUTOLOAD" method that makes it spring into existence the first
               time that it is called; see perlsub.

               Use of "defined" on aggregates (hashes and arrays) is
               deprecated.  It used to report whether memory for that
               aggregate had ever been allocated.  This behavior may disappear
               in future versions of Perl.  You should instead use a simple
               test for size:

                   if (@an_array) { print "has array elements\n" }
                   if (%a_hash)   { print "has hash members\n"   }

               When used on a hash element, it tells you whether the value is
               defined, not whether the key exists in the hash.  Use "exists"
               for the latter purpose.

               Examples:

                   print if defined $switch{D};
                   print "$val\n" while defined($val = pop(@ary));
                   die "Can't readlink $sym: $!"
                       unless defined($value = readlink $sym);
                   sub foo { defined &$bar ? &$bar(@_) : die "No bar"; }
                   $debugging = 0 unless defined $debugging;

               Note:  Many folks tend to overuse "defined" and are then
               surprised to discover that the number 0 and "" (the zero-length
               string) are, in fact, defined values.  For example, if you say

                   "ab" =~ /a(.*)b/;

               The pattern match succeeds and $1 is defined, although it
               matched "nothing".  It didn't really fail to match anything.
               Rather, it matched something that happened to be zero
               characters long.  This is all very above-board and honest.
               When a function returns an undefined value, it's an admission
               that it couldn't give you an honest answer.  So you should use
               "defined" only when questioning the integrity of what you're
               trying to do.  At other times, a simple comparison to 0 or ""
               is what you want.

               See also "undef", "exists", "ref".

Relaterede emner

Andre artikler