Je suis d'ajouter dynamiquement des classes, méthodes et attributs à l'aide Moose :: Meta :: Class.même appel de fonction apporter des résultats différents dans les internes de l'objet?
Quelqu'un peut-il expliquer pourquoi ce code fonctionne (appel interne sous-programme generate()
, à l'intérieur Cat
classe):
package Cat;
use Moose;
sub generate {
my $siberian = Moose::Meta::Class->create('Siberian');
$siberian->add_method(echo => sub { print "yeah!\n" });
my $tiger = Moose::Meta::Class->create('Tiger');
$tiger->add_attribute(
Siberian => {
is => 'ro',
default => sub { $siberian->new_object; }
},
);
__PACKAGE__->meta->add_attribute(
Tiger => {
is => 'ro',
default => sub { $tiger->new_object },
},
);
print "Generation done!\n";
}
generate();
package main;
use Data::Printer;
my $a = Cat->new;
# $a->generate;
p($a);
$a->Tiger->Siberian->echo; # returns 'yeah!'
sortie p($a)
:
Cat {
Parents Moose::Object
public methods (3) : generate, meta, Tiger
private methods (0)
internals: {
Tiger Tiger
}
}
et celui-ci (appelant generate
sous l'extérieur, via $a->generate
) ne fait pas:
package Cat;
use Moose;
sub generate {
my $siberian = Moose::Meta::Class->create('Siberian');
$siberian->add_method(
echo => sub { print "yeah!\n" }
);
my $tiger = Moose::Meta::Class->create('Tiger');
$tiger->add_attribute(
Siberian => {
is => 'ro',
default => sub { $siberian->new_object; }
},
);
__PACKAGE__->meta->add_attribute(
Tiger => {
is => 'ro',
default => sub { $tiger->new_object },
},
);
print "Generation done!\n";
}
# generate();
package main;
use Data::Printer;
my $a = Cat->new;
$a->generate;
p($a);
$a->Tiger->Siberian->echo; # returns 'yeah!'
sortie p($a)
:
Cat {
Parents Moose::Object
public methods (3) : generate, meta, Tiger
private methods (0)
internals: {}
}
et le programme renvoie une erreur:
Can't call method "Siberian" on an undefined value at base2.pl line 39.
Parce que quand vous appelle $ a-> vous ajoutez cette générer à la classe Cat attribut, pas à l'instance de cette classe Cat ($ a). Et même si vous ajoutez à l'instance (objet) ce champ ne sera pas initialisé. –