gpt4 book ai didi

perl - 我可以在包中注入(inject) perl 子程序吗?

转载 作者:行者123 更新时间:2023-12-04 10:47:40 25 4
gpt4 key购买 nike

我希望能够在类中动态“注入(inject)”方法,类似于 Mojolicious 助手的情况。像这样的东西:

my $s = SomeThing->new;

$s->helper(do_this => sub {
my $self = shift;
$foo = shift;
});

$s->do_this('bar');

我已经走了一段距离,但我希望被注入(inject)的潜艇在它们注入(inject)的类的命名空间中运行,而不是在 main 中运行。一。换句话说,这目前的工作方式如下:
$s->do_this('bar');

print 'in main: ', $foo;

这会打印出“bar”——我不希望这样,而我希望这样
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
}
}
};

有没有办法做到这一点?我怀疑我会搞砸严格性真的很糟糕 - 但我还不想放弃(这将是一个很好的学习技巧)。

最佳答案

您要求更改与已编译的匿名子关联的包以进行变量查找。我不知道这是否可能。

即使有可能,这也不是您想要做的事情,因为您的代码仍然无法工作。您必须添加 use vars qw( foo );sub { } 所在的文件找到文字。除了使用 our $foo;use vars qw( $foo );Something.pm如果你在那里访问它。

这是相当神奇和困惑。使用访问器很容易避免这种情况。简单替换

$s->helper(
do_this => sub {
my $self = shift;
$foo = shift;
},
);


$s->helper(
do_this => sub {
my $self = shift;
$self->foo(shift);
},
);

如果您还需要添加访问器,则可以使用以下内容:
$s->helper(
foo => sub {
shift;
state $foo;
$foo = shift if @_;
$foo
},
do_this => sub {
my $self = shift;
$self->foo(shift);
},
);

顺便说一句, monkey_patch来自 Mojo::Util可用作 helper 的替代品. (感谢@brian d foy 提出的。)它做同样的事情,但它有两个额外的好处:
  • 你不需要支持它。
  • 它设置匿名子的名称,以便堆栈跟踪使用有意义的名称而不是 __ANON__ .

  • 切换到 monkey_patch不能解决您的问题,但除了我上面提到的方法的改变之外,我确实建议使用它(或类似的)。
    use Mojo::Util qw(  );
    sub helper { shift; Mojo::Util::monkey_patch(__PACKAGE__, @_); }

    关于perl - 我可以在包中注入(inject) perl 子程序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59627050/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com