Я хотел бы иметь возможность «вводить» методы в класс на лету, подобно тому, как это происходит с помощниками Мооджилиуса. Примерно так:
my $s = SomeThing->new;
$s->helper(do_this => sub {
my $self = shift;
$foo = shift;
});
$s->do_this('bar');
Я сделал это на некотором расстоянии, но я бы хотел, чтобы подводные лодки, которые получают инъекцию, работали в пространстве имен класса, в который они вводятся, а не в main
один. Другими словами, в настоящее время это работает следующим образом:
$s->do_this('bar');
print 'in main: ', $foo;
это печатает "бар" - и я бы этого не хотел, в то время как я хотел бы это
print 'in SomeThing: ', $SomeThing::foo;
вместо «bar» печатать
, хотя это работает, но мне кажется неуклюжим
$s->helper(do_this => sub {
my $self = shift;
${(ref $self) . '::foo'} = shift;
});
$s->do_this('foo');
print 'in SomeThing: ', $SomeThing::foo; # now this prints "foo"
Пакет, в котором все это происходит, выглядит следующим образом:
package SomeThing {
use Mojo::Base -base;
use Carp;
sub helper {
my $self = shift;
my $name = shift || croak "The helper name is required";
my $sub = shift || sub {};
my $namespace = __PACKAGE__;
no strict 'refs';
{
*{"$namespace\::$name"} = $sub
}
}
};
Есть ли способ сделать это? Я подозреваю, что очень плохо испортил бы строгость - но я вроде бы пока не хочу сдаваться (и было бы неплохо научиться этому).