gpt4 book ai didi

perl - 深度嵌套 Perl 模块中仅供内部使用的类 - 避免尴尬的命名

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

假设有一个名为 MyApplication/Subcomponent.pm 的 Perl 模块,并且像往常一样,该文件以 package MyApplication::Subcomponent; 开头,该模块恰好定义了实用程序的集合功能。这些实用程序函数之一需要创建一个本地的、仅供内部使用的类的实例。类的定义非常简单,所以我将其粘贴到这里。这是RAII保存和恢复环境变量值的类。

{
package MyApplication::Subcomponent::restore_ENV_THING;

sub DESTROY {
my $self = shift;
$ENV{THING} = ${ $self };
}

sub new {
my $class = shift;
my $old_value = $ENV{THING};
$ENV{THING} = shift;
return bless \$old_value, $class;
}
}

据我所知,我必须在包名称的全局空间中为此类命名,并且必须从根开始命名:我不能只写 package restore_ENV_THING;因为这会破坏命名空间的顶层

所以问题是:如果有的话,我可以做什么,以便使用这个类的代码——保证与上面的代码块位于同一个文件中,并且在词法上位于下面它——可以写成

sub utility_routine_that_needs_to_save_and_restore_THING {
my $restorer = restore_ENV_THING->new($temporary_value);
...
}

而不是

sub utility_routine_that_needs_to_save_and_restore_THING {
my $restorer = MyApplication::Subcomponent::restore_ENV_THING
->new($temporary_value);
...
}

如果你知道一个技巧,可以让我不必在包名称的全局空间中为类命名(也许与打开我的 $fh 的内容并不完全不同, ... 是吗?)我也想听听这个。


请注意,MyApplication对其代码有一些不寻常的限制:

  • 受支持的最旧 Perl 版本是 5.006。是的,你没有看错,5.006。特别是这意味着我不能使用词法作用域的 subs。
  • 不能使用 CPAN 模块,只能使用自 5.006 起标准库中包含的模块。这就是为什么我不只使用 GuardScope::Guard ,以及为什么我使用基元手动定义类。
  • 本身无法发送任何 XS 代码。这就是为什么我在 RAII 中使用 sub DESTROY ,尽管如果调用者中对保护对象处理不当,这将无法正常工作;据我所知,如果不降级到 C 就没有办法做得更好。

最佳答案

有一个包裹吗alias做什么?

{
package MyApplication::Subcomponent::restore_ENV_THING;

BEGIN {
*MS:: = *MyApplication::Subcomponent::; # (initials for name)?
};

sub DESTROY {
my $self = shift;
$ENV{THING} = ${ $self };
}

sub new {
my $class = shift;
my $old_value = $ENV{THING};
$ENV{THING} = shift;
return bless \$old_value, $class;
}
}

现在它可以用作 MS::restore_ENV_THING

这是所有包和作用域的全局变量,是编译时别名。它确实与 main:: 符号表混在一起,但只要您选择一个“免费”名称就应该没问题。

还有一些包,例如 aliased杂注,Package::Alias ,以及其他一些,但它们确实有微妙之处,所以我建议先阅读它们。每当我使用它时,我发现如上所示的内置别名是一个很好的解决方案。

关于perl - 深度嵌套 Perl 模块中仅供内部使用的类 - 避免尴尬的命名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63872393/

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