2011-06-27 15 views
6

W moim zgłoszeniu pervious question zapytałem, jak korzystać z wielu modułów przy jednym użyciu. Dostałem jeden perfect answer i another one co zwróciło mi uwagę na moduł Modern::Perl, co jest naprawdę proste.Perl: wyjaśnienie, jak działa moduł "uni :: perl" - ładowanie pragmy i innych modułów

Po nieco poszukiwania cpan znalazłem kolejny moduł o nazwie uni::perl, co jest bardzo skomplikowane - to i ekwiwalent za:

use strict; 
use feature qw(say state switch); 
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 (:utf8 :std); 
use mro 'c3'; 

Może ktoś wyjaśnić/skomentować go, jak jego dzieła?

Wkleiłem cały kod tutaj podzielony na kilka segmentów i dodano moje pytania do (z ###).

Rozumiem, że to pytanie jest naprawdę długie. Ale podzielenie go na mniejszy nie pomoże, ponieważ całość dotyczy modułu "uni :: perl".

Proszę, pomóżcie mi zrozumieć problematyczne części.


package uni::perl; 
use 5.010; 
BEGIN { 
    ### OK - these are bitmask of different warnings, they're coming from: 
    # paste this into perl to find bitmask 
    # 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); 
    # BEGIN { warn join "", map "\\x$_", unpack "(H2)*", ${^WARNING_BITS}; exit 0 }; 

    ${^WARNING_BITS} ^= ${^WARNING_BITS}^"\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03"; 
    $^H |= 0x00000602; ### this mean "use strict;" 
} 

Ustawianie bezpośrednio z ${^WARNING_BITS} się z $^H, jest szybszy niż wspólna "use strict" i etc?


Co to jest m{ }x.

m{ 
use strict; 
use warnings; 
}x; 
use mro(); 

znam „dopasowaniu” operator i „x” flagę, ale nie rozumiem, co robi w tym kontekście .. use mro jest jakiś „ciemno-magiczny”, co zapewne wspólne Perl użytkownicy nie muszą wiedzieć ...;)


Co robi linia local *__ANON__? Co jest dobre w tym kontekście? Cały następny blok BEGIN to dla mnie mroczna magia. .?; (

BEGIN { 
    for my $sub (qw(carp croak confess)) { 
     no strict 'refs'; 
     *$sub = sub { ### for what need replace the global *croak (etc) with this sub? 
      my $caller = caller; 
      local *__ANON__ = $caller .'::'. $sub; ### what's mean this? 
      require Carp; 

        ### This set the Carp code-refs to the global namespace? 
        ### But who is the "caller" in the BEGIN block? (compile time) 

      *{ $caller.'::'.$sub } = \&{ 'Carp::'.$sub }; 

      goto &{ 'Carp::'.$sub }; ### Why need goto here? 
     }; 
    } 
} 

Wreszcie - niektóre jaśniejsze rzeczy Przepisz import tak, to zostanie wywołana gdy use uni::perl;

sub import { 
    my $me = shift; 
    my $caller = caller; 

    ### OK - again the bitmasks 
    ${^WARNING_BITS} ^= ${^WARNING_BITS}^"\xfc\x3f\xf3\x00\x0f\xf3\xcf\xc0\xf3\xfc\x33\x03"; 


    ### where are these documented? 
    $^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"); 


    ### again coderef magic. As I understand it - it will replace the 
    ### "carp, etc" in the callers namespace with the coderef's defined 
    ### in the above BEGIN block. But why with this complicated way? 

    for my $sub (qw(carp croak confess)) { 
     no strict 'refs'; 
     *{ $caller .'::'. $sub } = \&$sub; 
    } 

    ### and finally - I have abosolutely no idea - what do the next code 
    ### will take arguments of "use uni::perl qw(arg)" 
    ### but have no idea how to use it - or what is doing ;(
    while (@_) { 
     my $feature = shift; 
     if ($feature =~ s/^://) { 
      my $package = $me. '::'. $feature; 
      eval "require $package; 1" or croak("[email protected]"); 
      $package->load($caller); 
     } 
    } 
} 

co robi ostatni while

pytanie Plus:

  • dlaczego robią to samo dwa razy? Raz w bloku BEGIN i raz w imporcie? (Import jest do „użytkowania” - ale dlaczego robi prawie to samo w bloku „begin” zbyt

Ponieważ kwestia ta ma więcej części, proszę zacytować odpowiedni fragment, kiedy dajesz odpowiedź

?.

DZIĘKUJEMY WSZYSTKO W ADVANCE.

Odpowiedz

3
  1. Ustawianie bitów ostrzegawczych bezpośrednio jest nieco szybsza i ma bardziej przewidywalne zachowanie (widać wszystko, co powinno się zdarzyć), ale to jest oczywiście o wiele trudniejsze do pracy i utrzymaniu. Być może zestaw ostrzeżeń, które próbuje załadować zestaw uni::perl, jest łatwiejszy dzięki bitmaskom.

  2. m{ use strict; use warnings;}x; to po prostu wyrażenie w pustym kontekście. Wystąpiłby błąd dotyczący kontekstu lub nie zostałby ustawiony, gdyby były włączone ostrzeżenia. Nie jestem do końca pewien, dlaczego tak się dzieje, może to być uspokoić jakiś system metryczny kodu, który szuka linii "ostrzeżenia użycia, użyj ścisłego". Najprawdopodobniej napisałbym to, co najmniej trochę jaśniejsze.

  3. Ten blok BEGIN tworzy niestandardowe wersje funkcji karpi. Używa linii local *__ANON__ = ..., aby ustawić nazwę dowolnego anonimowego podprogramu, aby śledzenie stosu karpia było łatwiejsze do naśladowania. Blok BEGIN tworzy zapakowane procedury Karpi. Podprogram importu ładuje te nowe zawijane procedury do przestrzeni nazw wywołującego.

  4. To ostatnie wydaje się być ładowanie dodatkowych modułów wtyczek dla uni::perl.

  5. To samo nie jest zrobione, patrz odpowiedź na # 3. (BEGIN tworzy zapakowane procedury, import instaluje je w przestrzeni wywołującej)