Perl:解释如何使用;uni::perl“;模块-加载pragmas和其他模块
在我的演讲中,我问了如何一次使用多个模块。有一个,是什么让我想到了真正简单的模块 在对CPAN进行了一点搜索后,我发现了另一个名为的模块,这是一个非常复杂的模块,相当于:Perl:解释如何使用;uni::perl“;模块-加载pragmas和其他模块,perl,Perl,在我的演讲中,我问了如何一次使用多个模块。有一个,是什么让我想到了真正简单的模块 在对CPAN进行了一点搜索后,我发现了另一个名为的模块,这是一个非常复杂的模块,相当于: use strict; use feature qw(say state switch); no warnings; use warnings qw(FATAL closed threads internal debugging pack substr malloc unopened porta
use strict;
use feature qw(say state switch);
no warnings;
use warnings qw(FATAL closed threads internal debugging pack substr malloc
unopened portable prototype inplace io pipe unpack regexp
deprecated exiting glob digit printf utf8 layer
reserved parenthesis taint closure semicolon);
no warnings qw(exec newline);
use utf8;
use open (:utf8 :std);
use mro 'c3';
有人能解释/评论它是如何工作的吗?
我将整个代码粘贴到这里,分为几个部分,并将我的问题添加到(带有###
)
我知道这个问题很长。但是,将其划分为较小的模块并没有帮助,因为整个模块都是关于“uni::perl”模块的
请帮我理解有问题的部分
直接将
${^WARNING\u BITS}
设置为$^H
,比常见的“use strict”等更快
这是做什么的
m{}x
m{
use strict;
use warnings;
}x;
use mro ();
我知道“match”操作符和“x”标志,但不了解在这种情况下做了什么<代码>使用mro是一些普通perl用户可能不需要知道的“黑魔法”…)
local*\uuu ANON\uu
行是什么?在这种情况下,goto
有什么好处?
下一个街区对我来说是一个魔咒;(
最后-一些更清楚的事情。重写
导入
,这样,当使用uni::perl;
sub import {
my $me = shift;
my $caller = caller;
### OK - again the bitmasks
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
### where are these documented?
$^H |=
0x00000602 # strict
| 0x00800000 # utf8
;
# use feature
$^H{feature_switch} =
$^H{feature_say} =
$^H{feature_state} = 1;
# use mro 'c3';
mro::set_mro($caller, 'c3');
#use open (:utf8 :std);
${^OPEN} = ":utf8\0:utf8";
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");
### again coderef magic. As I understand it - it will replace the
### "carp, etc" in the callers namespace with the coderef's defined
### in the above BEGIN block. But why with this complicated way?
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*{ $caller .'::'. $sub } = \&$sub;
}
### and finally - I have abosolutely no idea - what do the next code
### will take arguments of "use uni::perl qw(arg)"
### but have no idea how to use it - or what is doing ;(
while (@_) {
my $feature = shift;
if ($feature =~ s/^://) {
my $package = $me. '::'. $feature;
eval "require $package; 1" or croak( "$@" );
$package->load( $caller );
}
}
}
最后一个正在做什么
补充问题:
- 为什么同样的事情要做两次?一次在开始块中,一次在导入块中?(导入是为了“使用”-但是为什么在“开始”块中也要做几乎相同的事情呢
因为这个问题有更多的部分,请在回答时引用相关部分
提前谢谢大家
直接设置警告位要快一点,并且具有更可预测的行为(您可以看到应该发生的一切),但显然更难使用和维护。可能是uni::perl
试图加载的警告集更容易通过位掩码完成
m{use strict;use warnings;}x;
只是void上下文中的一个正则表达式。如果启用了警告,它将抛出一个关于上下文或未设置$\uuuu
的错误。我不清楚为什么会这样做,可能是为了安抚一些代码度量系统,这些系统会查找“use warnings;use strict”行。如果0;
至少更清楚一点,我可能会编写它
local*\uuuuu ANON\uuuu=…
行设置任何匿名子例程的名称,以便Carp堆栈跟踪更易于遵循。BEGIN块创建包装的Carp例程。导入子例程然后将这些新包装的例程加载到他使用了调用方的名称空间uni::perl
加载额外的插件模块BEGIN
创建包装的例程,import
将它们安装到调用方的空间中)BEGIN {
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*$sub = sub { ### for what need replace the global *croak (etc) with this sub?
my $caller = caller;
local *__ANON__ = $caller .'::'. $sub; ### what's mean this?
require Carp;
### This set the Carp code-refs to the global namespace?
### But who is the "caller" in the BEGIN block? (compile time)
*{ $caller.'::'.$sub } = \&{ 'Carp::'.$sub };
goto &{ 'Carp::'.$sub }; ### Why need goto here?
};
}
}
sub import {
my $me = shift;
my $caller = caller;
### OK - again the bitmasks
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
### where are these documented?
$^H |=
0x00000602 # strict
| 0x00800000 # utf8
;
# use feature
$^H{feature_switch} =
$^H{feature_say} =
$^H{feature_state} = 1;
# use mro 'c3';
mro::set_mro($caller, 'c3');
#use open (:utf8 :std);
${^OPEN} = ":utf8\0:utf8";
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");
### again coderef magic. As I understand it - it will replace the
### "carp, etc" in the callers namespace with the coderef's defined
### in the above BEGIN block. But why with this complicated way?
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*{ $caller .'::'. $sub } = \&$sub;
}
### and finally - I have abosolutely no idea - what do the next code
### will take arguments of "use uni::perl qw(arg)"
### but have no idea how to use it - or what is doing ;(
while (@_) {
my $feature = shift;
if ($feature =~ s/^://) {
my $package = $me. '::'. $feature;
eval "require $package; 1" or croak( "$@" );
$package->load( $caller );
}
}
}