如何制作“使用我的::默认值"使用现代 perl &utf8 默认值? [英] How to make "use My::defaults" with modern perl & utf8 defaults?
问题描述
我想为我自己的默认用途"制作一个模块,例如:
I want make a module for my own "default use", e.g.:
use My::perldefs;
具有以下内容(主要基于tchrist 的帖子.)
with the following content (mostly based on tchrist's post.)
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
来实现
Simply, want achieve one use My::perldefs
for achieving
- 完整且正确的 utf8 支持,并带有
- 已开启所有现代 perl 功能.
基于最近的问题,好的起点是 uni::perl.它几乎可以做我想做的所有事情,只需要添加:
Based on recent question the good start-point is uni::perl. It is do nearly all things what I want, only need add:
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 使用制作一个好的样板.谢谢.
Please, HELP make an good boilerplate for utf8 and modern perl use. Thanks.
Bellow 是 uni::perl 的副本.
Bellow is the copy of uni::perl.
package My::perldefs;
use 5.014;
BEGIN {
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "xfcx3fxf3x00x0fxf3xcfxc0xf3xfcx33x03";
$^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} ^ "xfcx3fxf3x00x0fxf3xcfxc0xf3xfcx33x03";
$^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 :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
通过 Exporter
定义一个 export
方法,该方法将调用包作为参数).棘手的是autodie
,它确实严格按照caller
的值执行,并且通常会将其函数注入到My::perldefs
包中.我认为这里唯一好的解决方案(没有在 My::perldefs
中重新实现模块)是使用 goto
- 这允许在不更改 caller<的情况下调用所需的方法/code>,所以方法被注入到正确的命名空间中.这是我最后得到的:
use feature qw(unicode_strings)
is easy, $^H{feature_unicode}
simply needs to be set. The other modules aren't too hard as well, one simply needs to use require
and call the necessary module functions explicitly (e.g. Encode
and Unicode::Normalize
define an export
method via Exporter
that takes the calling package as a parameter). The tricky one is autodie
, it really goes strictly by the value of caller
and will normally inject its functions into My::perldefs
package. I think the only good solution here (short of reimplementing the module in My::perldefs
) is using goto
- this allows calling the required method without changing caller
, so the methods are injected into the correct namespace. Here is what I got in the end:
package My::perldefs;
use 5.014;
BEGIN {
${^WARNING_BITS} ^= ${^WARNING_BITS} ^ "xfcx3fxf3x00x0fxf3xcfxc0xf3xfcx33x03";
$^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} ^ "xfcx3fxf3x00x0fxf3xcfxc0xf3xfcx33x03";
$^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 :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 &utf8 默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!