2011-06-27 10 views
6

En mi pervious question pregunté cómo usar múltiples módulos con un solo uso. Tengo uno perfect answer, y another one lo que me señaló al módulo Modern::Perl lo que es realmente simple.Perl: explicación de cómo funciona el módulo "uni :: perl" - cargando pragmas y otros módulos

Después de un poco en busca de CPAN encontré otro módulo llamado uni::perl, lo que es realmente complicado - y es equivalente a:

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'; 

¿Puede alguien explicar/comentar que la forma en sus obras?

Pegué todo el código aquí dividido en pocos segmentos y agregué mis preguntas en, (con ###).

Entiendo que esta pregunta es muy larga. Pero dividirlo en uno más pequeño no ayudará, porque el todo se trata del módulo "uni :: perl".

Por favor, ayúdame a entender las partes problemáticas.


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;" 
} 

directamente la configuración del ${^WARNING_BITS} una la $^H, es más rápido que un común "use strict" y etc?


¿Qué está haciendo esto? m{ }x.

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

Sé que el operador "partido" y la bandera 'x', pero no entender lo que está haciendo en este contexto .. use mro es un poco de "magia oscura" lo que, probablemente, un Perl usuarios comunes no necesitan saber ...;)


Qué a hacer la línea local *__ANON__? ¿Para qué sirve el goto en este contexto? Todo el próximo bloque BEGIN es una magia oscura para mí. .?; (

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? 
     }; 
    } 
} 

Finalmente - algunas cosas más claras reescribir la import así, este será llamado cuando 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); 
     } 
    } 
} 

lo que está haciendo el último while

pregunta Plus:

  • ¿por qué hacer las mismas cosas dos veces? Una vez en el bloque BEGIN y una vez en importación? (Importación es para la "utilización" - pero ¿por qué hacer casi lo mismo que en el bloque "BEGIN" demasiado

Debido a esta pregunta tiene más partes, por favor, cita la parte pertinente cuando se le da una respuesta

?.

MUCHAS GRACIAS POR ADELANTADO.

Respuesta

3
  1. Configuración de los bits de advertencia directa es un poco más rápido, y tiene un comportamiento más predecible (se puede ver todo lo que debería suceder), pero es obviamente mucho más difícil de trabajar y mantener. Puede ser que el conjunto de advertencias que uni::perl está tratando de cargar sea más fácil a través de las máscaras de bits.

  2. m{ use strict; use warnings;}x; es simplemente una expresión regular en contexto vacío. Arrojaría un error ya sea sobre el contexto o $_ no estableciéndose si las advertencias fueron habilitadas. No estoy seguro exactamente de por qué se hace esto, podría ser para apaciguar algún sistema métrico de código que busque las líneas "use warnings; use strict". Probablemente lo habría escrito q{...} if 0;, que al menos es un poco más claro.

  3. Este bloque BEGIN está creando versiones personalizadas de las funciones en Carp. Está utilizando la línea local *__ANON__ = ... para establecer el nombre de cualquier subrutina anónima para que el seguimiento de pila de Carp sea más fácil de seguir. El bloque BEGIN crea las rutinas de Carpa envueltas. La subrutina de importación luego carga estas nuevas rutinas envueltas en el espacio de nombres de la persona que llama.

  4. Este último parece estar cargando módulos de complemento adicionales para uni::perl.

  5. Lo mismo no se está haciendo, vea la respuesta al n. ° 3. (BEGIN crea las rutinas envueltos, import les instala en el espacio de la persona que llama)

Cuestiones relacionadas