【发布时间】:2011-09-23 13:28:32
【问题描述】:
在我的pervious question 中,我询问了如何一次使用多个模块。有一个 perfect answer 和 another one 指向我的 Modern::Perl 模块非常简单。
在 CPAN 中搜索了一下后,我发现了另一个名为 uni::perl 的模块,真正复杂的是 - 它相当于:
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”模块的。
请帮我理解有问题的部分。
package uni::perl;
use 5.010;
BEGIN {
### OK - these are bitmask of different warnings, they're coming from:
# paste this into perl to find bitmask
# 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);
# BEGIN { warn join "", map "\\x$_", unpack "(H2)*", ${^WARNING_BITS}; exit 0 };
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
$^H |= 0x00000602; ### this mean "use strict;"
}
直接设置${^WARNING_BITS} 和$^H,比普通的“use strict”等更快吗?
这是在做什么m{ }x。
m{
use strict;
use warnings;
}x;
use mro ();
我知道“匹配”运算符和“x”标志,但不明白在这种情况下在做什么。use mro 是一些“黑暗魔法”,可能是普通 perl 用户不需要知道的。 . ;)
local *__ANON__ 行是做什么的?在这种情况下,goto 有什么好处?
整个下一个 BEGIN 块对我来说是一个黑魔法。 ;(
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?
};
}
}
最后 - 一些更清晰的东西。重写import这样,当use 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 );
}
}
}
最后一个while在做什么?
加号问题:
- 为什么做同样的事情两次?一次在 BEGIN 块中,一次在导入中? (导入是为了“使用”——但是为什么在“开始”块中也做几乎相同的事情呢?
由于本题部分较多,请在回答时引用相关部分。
提前谢谢大家。
【问题讨论】:
标签: perl