В моем предыдущем вопросе Я спросил, как использовать несколько модулей за одно использование. Получил один идеальный ответ и другой , что указало мне на 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
, быстрее, чем обычное «строгое использование» и т. Д.
Что это делает m{ }x
.
m{
use strict;
use warnings;
}x;
use mro ();
Я знаю оператор "match" и флаг "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 и один раз в импорте? (импорт предназначен для «использования» - но зачем делать то же самое в блоке «НАЧАЛО»?
Поскольку этот вопрос состоит из нескольких частей, пожалуйста, укажите соответствующую часть, когда вы даете ответ.
СПАСИБО ВСЕМ В ПРЕДЕЛАХ.