我想为我自己的“默认使用”制作一个模块,例如:
use My::perldefs;
具有以下内容(主要基于 tchrist's 帖子。)
use 5.014;
use strict;
use features qw(switch say state);
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 qw(:std :utf8);
use charnames qw(:full);
use feature qw(unicode_strings);
use Encode qw(encode decode);
use Unicode::Normalize qw(NFD NFC);
use Carp qw(carp croak confess cluck);
use autodie;
简单来说,想实现一个
use My::perldefs
为了达到基于 recent question好的起点是 uni::perl。它几乎可以做我想做的所有事情,只需要添加:
use feature qw(unicode_strings);
use charnames qw(:full);
use Encode qw(encode decode);
use Unicode::Normalize qw(NFD NFC);
use autodie;
我将奖励使用有效且正确的方式用上述 5 行扩展 uni::perl(下面插入)的人。
请帮助为 utf8 和现代 perl 使用制作一个很好的样板。谢谢。
Bellow 是 uni::perl 的副本。
package My::perldefs;
use 5.014;
BEGIN {
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
$^H |= 0x00000602;
}
m{
use strict;
use warnings;
}x;
use mro ();
BEGIN {
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*$sub = sub {
my $caller = caller;
local *__ANON__ = $caller .'::'. $sub;
require Carp;
*{ $caller.'::'.$sub } = \&{ 'Carp::'.$sub };
goto &{ 'Carp::'.$sub };
};
}
}
sub import {
my $me = shift;
my $caller = caller;
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
$^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");
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*{ $caller .'::'. $sub } = \&$sub;
}
while (@_) {
my $feature = shift;
if ($feature =~ s/^://) {
my $package = $me. '::'. $feature;
eval "require $package; 1" or croak( "$@" );
$package->load( $caller );
}
}
}
1;
附言:
All of the above is (C): Mons Anderson, C<< <mons at cpan.org> >>
最佳答案
use feature qw(unicode_strings)
很容易,$^H{feature_unicode}
只需要设置。其他模块也不太难,只需要使用require
并显式调用必要的模块函数(例如 Encode
和 Unicode::Normalize
通过 export
定义一个 Exporter
方法,将调用包作为参数)。棘手的是autodie
, 它确实严格按照 caller
的值进行并且通常会将其函数注入(inject) My::perldefs
包裹。我认为这里唯一好的解决方案(没有在 My::perldefs
中重新实现模块)是使用 goto
- 这允许在不更改 caller
的情况下调用所需的方法,因此这些方法被注入(inject)到正确的命名空间中。这是我最后得到的:
package My::perldefs;
use 5.014;
BEGIN {
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
$^H |= 0x00000602;
}
m{
use strict;
use warnings;
}x;
use mro ();
BEGIN {
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*$sub = sub {
my $caller = caller;
local *__ANON__ = $caller .'::'. $sub;
require Carp;
*{ $caller.'::'.$sub } = \&{ 'Carp::'.$sub };
goto &{ 'Carp::'.$sub };
};
}
}
sub import {
my $me = shift;
my $caller = caller;
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03";
$^H |=
0x00000602 # strict
| 0x00800000 # utf8
;
# use feature
$^H{feature_switch} =
$^H{feature_say} =
$^H{feature_state} =
$^H{feature_unicode}= 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");
#use charnames qw(:full)
require charnames;
charnames->import(":full");
#use Encode qw(encode decode)
require Encode;
Encode->export($caller, "encode", "decode");
#use Unicode::Normalize qw(NFC NFD)
require Unicode::Normalize;
Unicode::Normalize->export($caller, "NFC", "NFD");
for my $sub (qw(carp croak confess)) {
no strict 'refs';
*{ $caller .'::'. $sub } = \&$sub;
}
while (@_) {
my $feature = shift;
if ($feature =~ s/^://) {
my $package = $me. '::'. $feature;
eval "require $package; 1" or croak( "$@" );
$package->load( $caller );
}
}
#use autodie qw(:default)
#goto needs to be used here to make sure that caller doesn't change
require autodie;
@_ = ("autodie", ":default");
goto &autodie::import;
}
1;
关于perl - 如何使用现代 perl 和 utf8 默认值制作 "use My::defaults"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6412799/