2011-06-20 14 views
15

Ben, benim kendi "default kullanım" için bir modül yapmak örn istiyorum: (. Çoğunlukla tchrist's yazı dayanarak) aşağıdaki içeriği ileModern perl & utf8 varsayılanlarıyla "My :: defaultults" u nasıl kullanabilirim?

use My::perldefs; 

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; 

Basitçe, bir tane başarmak istiyoruz

  • tam ve doğru UTF-8 desteği elde etmek için use My::perldefs ve
  • ile
  • Tüm modern perl özellikleri açık.

recent question temel alındığında iyi bir başlangıç ​​noktası uni :: perl'dir. Bunu yapmak ise ben sadece eklemek gerek istediğini neredeyse tüm noktalar:

use feature qw(unicode_strings); 
use charnames qw(:full); 
use Encode qw(encode decode); 
use Unicode::Normalize qw(NFD NFC); 
use autodie; 

Yukarıda 5 çizgilerle (feryat inseretd) uni :: perl uzatacaktır kelle biriyle ödül, bir kullanma olacak etkili ve doğru bir şekilde.

Lütfen, YARDIM utf8 ve modern perl kullanımı için iyi bir boilerplate yapın. Teşekkürler.


Bellow, uni :: perl dosyasının bir kopyasıdır.

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("[email protected]"); 
      $package->load($caller); 
     } 
    } 
} 

1; 

Ps:

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

İlgili: [perl5i] (http://p3rl.org/perl5i), [perl5] (http://p3rl.org/perl5), [Toolkit] (http://p3rl.org/Toolkit). – daxim

+2

Ayrıca, [ToolSet] (http://search.cpan.org/perldoc?ToolSet) ilginizi çekebilir. – bvr

cevap

9

use feature qw(unicode_strings)$^H{feature_unicode} basitçe ayarlanması gerekir kolaydır. Diğer modüller de çok zor değil, birinin sadece require'u kullanması ve gerekli modül işlevlerini açıkça çağırması gerekiyor (örneğin Encode ve Unicode::Normalize, çağıran paketi bir parametre olarak alan Exporter aracılığıyla bir export yöntemi tanımlar). Zor olan, autodie, gerçekten caller değerine göre değişir ve normalde işlevlerini My::perldefs paketine enjekte eder. Bence buradaki tek iyi çözüm (My::perldefs modülünü reimplementing) goto kullanıyor - bu, caller değiştirmeden gerekli yöntemi çağırıyor, böylece yöntemler doğru ad alanına enjekte ediliyor. İşte sonunda ne var:

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("[email protected]"); 
      $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; 
+0

Autodie parçasını kullanırken, $ {^ OPEN} = ": utf8 \ 0: utf8"; - Çalışmayı durdurur. Yani, autodie parçası olmadan kullanacaktır. Her neyse, thanx. Başka bir deyişle, "autodie kullan" bir şekilde $ {^ OPEN} ile uyumlu değildir. – jm666

+0

heh - sadece bu http://stackoverflow.com/questions/4959384/does-the-autodie-pragma-have-influence-on-the-encoding/4959646#4959646 adresinde bilinen bir perl hatası bulundu. – jm666