2010-12-09 38 views
7

Quelle est la différence entre le construit en ref($object) et Scalar::Utilblessed($object)? Est-ce que l'un est préféré à l'autre?Scalar :: Util vs fonction de référence

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; 
} 
+0

Voir aussi: http://stackoverflow.com/questions/1399833/how-can-i-get-perls-ref-function-to-return-ref-io-and-lvalue/1400176#1400176 –

Répondre

7

Selon POD, blessed() ne fonctionne que sur des références bénies (par exemple, une des références passées à un appel bless()).

Il retourne undef sur tout le reste, y compris refs de hachage/tableau où ref() retours HASH/ARRAY (et un tas d'autres types comme définie dans perldoc ref). Pour obtenir le type de référence, vous pouvez, bien sûr, appeler Scalar::Util::reftype. Quant à savoir si l'un devrait être utilisé par rapport à un autre, je pense que cela dépend largement de ce que la logique est.

  • Si vous ne voulez distinguer des références réelles bénies de tout le reste, blessed() fournit une façon plus concise que de prendre un ref puis vérifier que la valeur est pas de les standards retournés par référence 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"; 
    
  • Si vous avez besoin des distinctions fines entre les deux références différentes et bénies les ublessed, un seul appel ref() est plus concise qu'une combinaison de blessed et reftype.

  • Un bord cas où il y a une différence fonctionnelle réelle entre les deux approches, comme indiqué dans les commentaires par Eric Strom, est quand quelqu'un crée une classe qui correspond à l'un des ref()hardcoded values (par exemple bless [], 'HASH' - auquel cas ils sont soit Way Dumb ou Way trop intelligent par moitié).

    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 
    

AVERTISSEMENT: Sur la base de la documentation, il devrait y avoir aucune différence entre les deux lorsque l'argument est une référence bénie dans une classe (par exemple, il retourne le nom de la classe). Mais je n'ai pas vérifié la source "Scalar :: Util" pour confirmer.

+4

Et sur le flipside, 'Scalar :: Util :: reftype' renvoie le type de référence sous-jacent (par exemple' HASH' ou 'GLOB' ou autre) même si son argument est béni. Fondamentalement 'reftype' et' béni 'découpler les deux choses différentes que le 'ref' intégré essaie de faire. – hobbs

+1

rien n'empêche quelqu'un d'écrire 'bless [], 'HASH'' ou autre folie qui causera des erreurs si seulement en utilisant' ref'. C'est là que 'béni 'et' reftype' sont très utiles –

+0

@Eric Strom: Le fait d'utiliser ou non 'ref' provoque des erreurs dépend de la manière dont on traite naïvement sa sortie. 'HASH = ARRAY (0x182a35c)' semble étrange mais vous * pouvez * extraire correctement la classe et le type de référence avant d'aller casser les rotules du sociopathe qui a nommé une classe "HASH". –