Scalar :: funzione vs. rif Util
-
25-09-2019 - |
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;
}
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 unref
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 diblessed
ereftype
. -
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 esbless [], '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.