2008-08-14 4 views
18

En Perl, un objet est simplement une référence à l'un des types de données Perl de base qui ont été bénis dans une classe particulière. Lorsque vous utilisez la fonction ref() sur une référence non balisée, vous êtes informé du type de données vers lequel pointe la référence. Cependant, lorsque vous appelez ref() sur une référence bénie, vous obtenez le nom du paquet dans lequel la référence a été bénie.Comment puis-je déterminer le type d'une référence bénie en Perl?

Je veux connaître le type sous-jacent de la référence bénie. Comment puis-je déterminer cela?

Répondre

18

Scalar::Util::reftype() est la solution la plus propre. Le module Scalar::Util a été ajouté au noyau Perl dans la version 5.7 mais est disponible pour les anciennes versions (5.004 ou ultérieures) du CPAN.

Vous pouvez également sonder avec UNIVERSAL::isa():

$x->isa('HASH')    # if $x is known to be an object 
UNIVERSAL::isa($x, 'HASH') # if $x might not be an object or reference 

De toute évidence, vous auriez aussi de vérifier ARRAY et SCALAR types. Le module UNIVERSAL (qui sert de classe de base pour tous les objets) fait partie du noyau depuis Perl 5.003.

Une autre façon - facile mais un peu sale - est de renforcer la référence. En supposant que la classe n'a pas surchargé mise en chaîne vous récupérerez quelque chose qui ressemble à Class=HASH(0x1234ABCD), que vous pouvez analyser pour en extraire le type de données sous-jacentes:

my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i); 
+3

Vous voulez juste eval {$ x-> isa ($ type)}; Si ce n'est pas un objet, vous revenez faux. Si ce n'est pas le bon type, vous obtenez faux, et si c'est le bon type, vous devenez vrai. :) –

2

Et ma première pensée à ce sujet était: "Les objets en Perl sont toujours des références hash, alors quel hack?"

Mais, Scalar :: Util :: reftype est la réponse. Merci d'avoir posé la question ici.

Voici un extrait de code pour le prouver .. (au cas où il serait utile à n'importe qui).

 
$> perl -e 'use strict; use warnings "all"; my $x = [1]; bless ($x, "ABC::Def"); use Data::Dumper; print Dumper $x; print ref($x) . "\n"; use Scalar::Util "reftype"; print reftype($x) . "\n"'` 

Sortie:

 
$VAR1 = bless([ 
       1 
       ], 'ABC::Def'); 
ABC::Def 
ARRAY 
+3

objets sont souvent mis en œuvre en tant que références de hachage, mais ce n'est pas une exigence. Un objet peut être n'importe quel type de référence. –

6

Vous ne devriez probablement pas faire cela. Le type sous-jacent d'un objet est un détail d'implémentation à ne pas confondre. Pourquoi voudriez-vous le savoir?

+0

D'accord, et je savais que quelqu'un ferait ce commentaire. Je n'avais vraiment besoin de cela qu'en essayant de comprendre une structure qu'un module était en train de créer afin de pouvoir modifier le module. Je voulais supprimer une clé particulière de tous les hachages dans la structure, car ils contenaient un JPEG brut. –

+2

Plus tard, j'ai découvert que je pouvais utiliser Data :: Dumper :: sortkeys pour filtrer ces données afin que Data :: Dumper ne produise pas mégaoctets de sortie binaire. –

Questions connexes