Escalar :: UTIL vs. Ref Função
-
25-09-2019 - |
Pergunta
Qual é a diferença entre os incorporados ref($object)
e Scalar::Util
blessed($object)
? Um é preferido sobre o outro?
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;
}
Solução
De acordo com POD, blessed()
só funciona em referências abençoadas (por exemplo, referências passadas para um bless()
ligar).
Ele retorna undef
em todo o resto, incluindo hash/array refs onde ref()
retorna HASH
/ARRAY
(e vários outros tipos delineados em PerlDoc Ref). Para obter o tipo de referência, você pode, é claro, ligue Scalar::Util::reftype
.
Quanto a se um deve ser usado em relação ao outro, acho que depende em grande parte do que é a lógica.
Se você só quero distinguir referências abençoadas de todo o resto,
blessed()
fornece uma maneira mais concisa do que tomar umref
e, em seguida, verificando que o valor não está no padrão retornado por referência não abençoada.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 você precisar de distinções finas entre as duas referências abençoadas e as diferentes, então um único
ref()
A chamada é mais concisa do que uma combinação deblessed
ereftype
.Um caso de borda em que há uma diferença funcional real entre as duas abordagens, como observado nos comentários de Eric Strom, é quando alguém cria uma classe que corresponde a um dos
ref()
valores codificados (por exemplo:bless [], 'HASH'
- nesse caso, eles são idiotas ou muito inteligentes pela metade).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
Isenção de responsabilidade: Com base na documentação, não deve haver diferença entre os dois quando o argumento é uma referência abençoada em uma classe (por exemplo, retorna o nome da classe). Mas não verifiquei a fonte "escalar :: util" para confirmar.