如何使用现代perl&utf8默认设置“使用My :: defaults”?

前端之家收集整理的这篇文章主要介绍了如何使用现代perl&utf8默认设置“使用My :: defaults”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想为自己的“默认使用”制作一个模块,例如:
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;

只需要实现一个使用My :: perldefs来实现

>完整和正确的utf8支持,并与
>所有现代的perl功能开启.

基于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(inseretd bellow)的使用有效和正确的方法的人.

请帮助为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;

PS:

All of the above is (C): Mons Anderson,C<< <mons at cpan.org> >>

解决方法

使用功能qw(unicode_strings)很简单,只需要设置$^ H {feature_unicode}.其他模块也不是太难,只需要明确地使用require并调用必要的模块功能(例如,Encode和Unicode :: Normalize通过导出器定义导出方法,该方法调用包作为参数).棘手的一个是autodie,它真的严格按照调用者的价值,通常会将其功能注入到My :: perldefs包中.我认为这里唯一很好的解决方案(在My :: perldefs中没有重新实现模块)正在使用goto – 这允许调用所需的方法而不改变调用者,因此这些方法被注入到正确的命名空间中.这是我得到的结局:
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,":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相关文章