gpt4 book ai didi

perl - 如何使用现代 perl 和 utf8 默认值制作 "use My::defaults"?

转载 作者:行者123 更新时间:2023-12-03 20:52:52 25 4
gpt4 key购买 nike

我想为我自己的“默认使用”制作一个模块,例如:

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为了达到
  • 完整且正确的 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(下面插入)的人。

    请帮助为 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并显式调用必要的模块函数(例如 EncodeUnicode::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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com