В моем вопросе прошивки я спросил, как использовать несколько модулей с одним использованием. Получил один отличный ответ и еще один, что указывало мне на 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}
a $^H
, быстрее, чем обычная "use strict" и т.д.
Что делает это 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 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 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( "[email protected]" );
$package->load( $caller );
}
}
}
что делает последний while
?
Плюс вопрос:
- зачем делать то же самое в два раза? Один раз в блоке BEGIN и один раз в импорте? (импорт предназначен для "использования" - но зачем делать почти то же самое в блоке "BEGIN"?
Поскольку этот вопрос содержит больше деталей, процитируйте соответствующую часть, когда вы даете ответ.
СПАСИБО ВАМ ВСЕ ПРЕДУСМОТРЕТЬ.