gpt4 book ai didi

perl - 如何在不禁用严格 'refs' 的情况下重命名 perl __ANON__ sub?

转载 作者:行者123 更新时间:2023-12-03 16:10:18 24 4
gpt4 key购买 nike

我找到了在 Perl here 中重命名匿名子的解决方案.它涉及临时修改符号表以插入所需的名称。此解决方案使用硬编码的符号表名称进行替换。我的问题是我想在运行时动态选择符号表名称。像这样的东西:

   $pkg = 'MyPkg::ModA::';
$name = 'subname';
...
no strict 'refs';
local *{"${pkg}__ANON__"} = "$name [anon]";
strict refs;
使其工作的唯一方法是禁用严格的引用。如果它们未被禁用,则脚本将失败并显示以下消息:
Can't use string ("MyPkg::ModA::__ANON__") as a symbol ref while "strict refs" in use at /path/to/source/File.pm line xx

Note that the equivalent statement could be used

   local ${$pkg}{__ANON__} = "$name [anon]";
带有类似的错误消息:
Can't use string ("MyPkg::ModA::") as a HASH ref while "strict refs" in use at /path/to/source/File.pm line xx

Is it possible to do the same thing without disabling strict refs?

TMI/DNR:
Here is a complete example in case you're interested. Ironically, my solution uses an anonymous sub to rename the given anonymous sub.

ModA.pm

package MyPkg::ModA;

use strict;
use warnings;
use MyPkg::Util;

# Create a new instance.
sub new
{
my ($type, $class, $self);

# allow for both ModA::new and $moda->new
$type = shift;
$class = ref $type || $type;
$self = {@_};
bless $self, $class;

# use exported Util::anon sub here
$self->{func} = anon sub
{
my ($arg);

$arg = shift;

debug "\$arg: $arg";
};

return $self;

} # new

1;
__END__
ModB.pm
package MyPkg::ModB;

use strict;
use warnings;
use MyPkg::ModA;

# Create a new instance.
sub new
{
my ($type, $class, $self);

# allow for both ModB::new and $modb->new
$type = shift;
$class = ref $type || $type;
$self = {@_};
bless $self, $class;

$self->{modA} = MyPkg::ModA->new;

return $self;

} # new

# Do something with ModA.
sub doit
{
my ($self);

$self = shift;

$self->{modA}->{func}->('What is your quest?');

} # doit

1;
__END__
实用程序.pm
package MyPkg::Util;

use strict;
use warnings;
require Exporter;

our (@ISA, @EXPORT);

@ISA = qw(Exporter);
@EXPORT = qw(
anon
debug);

# Temporarily mangle symbol table to replace '__ANON__'.
sub anon
{
my ($func, $sub, $pkg, $name);

$func = shift;

$sub = (caller 1)[3];
$sub =~ /(.*::)(.+)/;
$pkg = $1;
$name = $2;

return sub
{
# TODO How to do this w/o disabling strict?
#no strict 'refs';
# temp symbol table mangling here
# ${$pkg}{__ANON__} is equivalent to *{"${pkg}__ANON__"}
local *{"${pkg}__ANON__"} = "$name [anon]";
use strict;
$func->(@_);
};

} # anon

# Print a debug message.
sub debug
{
my($fname, $line, $sub);

($fname, $line) = (caller 0)[1,2];
$fname =~ s/.+\///;

$sub = (caller 1)[3] || 'main';
$sub =~ s/.*::(.+)/$1/;

printf STDERR "%-10s %s(%s) - \"%s\"\n", $fname, $sub, $line, "@_";

} # debug

1;
__END__
我的测试.pl
#! /usr/bin/perl

use strict;
use warnings;
use MyPkg::ModB;

# Stuff happens here.
my ($modB);

$modB = MyPkg::ModB->new;
$modB->doit;

最佳答案

您可以使用核心模块Sub::Utilset_subname .

use Sub::Util qw( set_subname );

sub anon {
...
return set_subname("$name [anon]", $func);
}

关于perl - 如何在不禁用严格 'refs' 的情况下重命名 perl __ANON__ sub?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64074462/

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