Domanda

Qual è la differenza tra il costruito nel ref($object) e Scalar::Util blessed($object)? È uno preferito sopra l'altro?

use strict;
use warnings;

use Scalar::Util qw(blessed isvstring);

my $object = foo->new();

print "Object is a " . blessed($object) . "\n";
print "Object is a " . ref($object) . "\n";

my $version = 5.00.03;

print "Version is a " . ref(\$version) . "\n";
if (isvstring($version)) {
    print "Version is a VSTRING\n";
}

package foo;
sub new {
    my $class = shift;
    my $self = {};

    bless($self, $class);
    return $self;
}
È stato utile?

Soluzione

Secondo POD, blessed() funziona solo su riferimenti benedetti (per esempio un riferimento passata a una chiamata bless()).

Si ritorna undef su tutto il resto, compreso hash / arbitri matrice in cui i rendimenti ref() HASH / ARRAY (e un sacco di altri tipi, come è definita in perldoc ref ). Per ottenere tipo di riferimento è possibile, naturalmente chiamata Scalar::Util::reftype.

Per quanto riguarda se uno deve essere utilizzato su un altro, penso che dipende in gran parte su ciò che la logica è.

  • Se solo vuole distinguere i riferimenti reali benedetti da tutto il resto, blessed() fornisce un modo più conciso che prendere un ref e quindi verificare che il valore non è su di quelli standard restituiti da riferimento unblessed.

    my $ref_type = ref($my_ref);
    print "USING REF: ";
    if (      $ref_type
           && $ref_type ne ref({})
           && $ref_type ne ref([])
           && $ref_type ne "SCALAR"
           # Could also use a hash with all allowed values of ref() instead
           && $ref_type !~ /^(CODE|REF|GLOB|...)$) { 
        print "I am an object of class $ref_type\n";
    } else {
        print "I'm a reference of type $ref_type\n";
    }
    
    
    # vs... 
    
    
    print "USING SCALAR_UTIL: ";
    my $ref_type = blessed($my_ref);
    print $ref_type ? "I am an object of class $ref_type\n"
                    : "I am a reference of type " . reftype($my_ref) . "\n";
    
  • Se avete bisogno di sottili distinzioni tra i due riferimenti benedetti e quelli ublessed diverse, quindi una sola chiamata ref() è più conciso di una combinazione di blessed e reftype.

  • Un bordo caso in cui ci sia una differenza funzionale vero e proprio tra i due approcci, come notato nei commenti di Eric Strom, è quando qualcuno crea una classe che corrisponde a uno dei ref() hardcoded valori (ad es bless [], 'HASH' - nel qual caso essi sono in entrambi i casi Dumb o Way Too Clever della metà).

    my $sssft = bless [], 'HASH'; # sssft = someone_should_suffer_for_this
    ref_description_using_ref($sssft);
    ref_description_using_scalar_util($sssft);
    
    
    # OUTPUT:
    USING REF: I'm a reference of type HASH
    USING SCALAR_UTIL: I am an object of class HASH
    

NOTA BENE: Sulla base di documentazione, non ci dovrebbe essere alcuna differenza tra i due quando l'argomento è un riferimento benedetta in una classe (ad esempio, restituisce il nome della classe). Ma non ho controllato "Scalar :: Util" fonte per confermare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top