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;
}
Foi útil?

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ê quero distinguir referências abençoadas de todo o resto, blessed() fornece uma maneira mais concisa do que tomar um ref 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 de blessed e reftype.

  • 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top