De perldoc -f bless :
bless REF,CLASSNAME
Cette fonction indique à la chose référencée par
REF
qu'il est maintenant
un objet dans leCLASSNAME
l'emballage.
Existe-t-il un moyen d'obtenir une structure non bénite sans faire de copies inutiles ?
De perldoc -f bless :
bless REF,CLASSNAME
Cette fonction indique à la chose référencée par
REF
qu'il est maintenant
un objet dans leCLASSNAME
l'emballage.
Existe-t-il un moyen d'obtenir une structure non bénite sans faire de copies inutiles ?
unbless($ref)
Retirer la bénédiction de tous les objets trouvés dans la structure de données transmise.
#!/usr/bin/perl
use strict; use warnings;
use Scalar::Util qw( refaddr );
use Data::Structure::Util qw( unbless );
my $x = bless { a => 1, b => 2 } => 'My';
printf "%s : %s\n", ref $x, refaddr $x;
unbless $x;
printf "%s : %s\n", ref $x, refaddr $x;
Sortie :
My : 237356
HASH : 237356
Data::Structure::Util dispose d'un unbless
qui le fera pour vous. Comme le souligne Erik, JSON::XS n'accepte normalement pas les références bénies (même si j'aimerais qu'il l'ignore et qu'il s'occupe de la structure de données). Il n'y a pas de moyen de contourner ce problème dans ce cas.
Mais réfléchissez à la raison pour laquelle vous pensez qu'il est nécessaire de le débloquer. Faites-vous cela pour l'une de vos propres classes ou pour une classe différente ? Cela ressemble étrangement à la mauvaise chose à faire. Il y a peut-être une meilleure solution.
Vous avez le même problème que la rupture de l'encapsulation car vous devez supposer que vous connaissez la structure interne de la référence. Si vous faites cela, vous pouvez simplement ignorer l'aspect orienté objet et accéder directement à la structure.
Si vous comptez le faire dans votre propre classe, envisagez de fournir une méthode permettant de renvoyer une structure de données (qui ne doit pas nécessairement être la structure d'origine) au lieu de modifier l'objet.
Vous mentionnez dans un commentaire de suivi que vous pourriez faire cela pour contourner certains comportements de Template Toolkit. J'ai fait face à cette situation de deux manières différentes, en fonction de la situation :
Perl est DWIM, mais TT est encore plus DWIM, ce qui est parfois regrettable.
Voici une petite astuce qui consiste à définir un fichier TO_JSON
en UNIVERSAL
et s'applique donc à tous les objets. Elle effectue une copie profonde, la débride et renvoie la structure de données.
#!perl
use v5.10;
sub UNIVERSAL::TO_JSON {
my( $self ) = shift;
use Storable qw(dclone);
use Data::Structure::Util qw(unbless);
my $clone = unbless( dclone( $self ) );
$clone;
}
my $data = bless {
foo => bless( [], 'Local::Array' ),
quack => bless( {
map { $_ => bless [$_, $_**2], 'Local::Array' }
grep { is_prime } 1 .. 10
}, 'Local::Hash' ),
}, 'Local::Hash';
use JSON::XS;
my $jsonner = JSON::XS->new->pretty->convert_blessed(1);
say $jsonner->encode( $data );
Unbless est souvent utile, comme lorsque vous déboguez un état interne et que vous voulez vider un objet béni dans une boucle serrée... avec json::xs parce que Dumper est 100 fois plus lent, et json::xs ne videra pas un objet béni.... même s'il s'agit juste d'une hashref.
Si vous savez par quoi votre objet est soutenu, vous pouvez le faire sans utiliser de paquets.
Hachures
$obj = bless {}, 'Obj';
print ref $obj, "\n";
$obj = { %$obj };
print ref $obj, "\n";
Tableau
$obj = bless [], 'Obj';
print ref $obj , "\n";
$obj = [ @$obj ];
print ref $obj, "\n";
Scalaire
$obj = bless \$a, "Obj";
print ref $obj, "\n";
$obj = \${ $$obj };
print ref $obj, "\n";
+1 parce que cela résout exactement mon problème, à savoir que je voulais juste accéder "temporairement" à la structure de données sous-jacente de l'objet (un Hash) pour facilement le Dump avec YAML::Tiny.
Mise à jour : Merci, Ivan ! J'ai confondu les modules. En fait, je voulais donner un lien vers Acme::Damn :))
P. S. Voir aussi Acme::Sneeze :)
P. P. S. Il n'a pas d'utilité réelle, c'est pourquoi il est Acme::
. Voir l'article de Brian.
Attribué à Mike Andrews dans alt.sysadmin.recovery : "Perl a déjà bénir et nous savons ce qu'il fait, n'est-ce pas ? Perl devrait également avoir frapper et nous savons aussi ce qu'il devrait faire. Si plus de langues avaient frapper mis en œuvre, les programmeurs restants seraient meilleurs que la moyenne actuelle".
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
Voir aussi perlmonks.org/?node_id=183348
0 votes
@Ether : Par exemple, Template::Toolkit. L'opérateur point
'.'
est utilisé pour accéder à des listes et à des hachages ou pour appeler des méthodes d'objets. TT essaie toujours une méthode objet en premier.4 votes
Pour information, j'ai besoin de
unbless
parce queYAML::Any::Dump()
conservera la nature bénite d'un objet, je ne veux pas stocker cela, mais parfois les hachages de données que je déverse sont bénis. AussiMoose->new
est très pointilleux et ne prend pas une hashref bénite comme argument.0 votes
Oui, l'abandon d'objets en est souvent la cause. Le commentaire "pourquoi auriez-vous besoin de cela" est souvent formulé par un idéologue. Elle est à la fois inutile, condescendante et révélatrice de l'ignorance.
5 votes
En fait, la question "pourquoi auriez-vous besoin de cela ?" tente souvent de mettre le doigt sur le vrai problème, car les gens demandent une solution dont ils pensent avoir besoin au lieu d'une cause (le "problème"). Problème XY ). Dans ce cas, le message original n'avait aucune motivation pour la solution suggérée.