2012-02-29 15 views
7

Digamos que creo una clase llamada Bar. El archivo comienza Bar.pmPerl class naming convention

package Bar; 

para evitar chocar con otros Bar clases, me puso el archivo en un subdirectorio Foo. Así que ahora, cuando se utiliza la clase, tengo que escribir

use Foo::Bar; 

Mi pregunta es, necesito para cambiar el nombre de la clase a Foo::Bar? En otras palabras, necesito para cambiar la primera línea de Bar.pm a

package Foo::Bar; 

? El problema es que, si hago esto, ahora debo referirme a la clase como Foo::Bar en todas partes, p.

my $obj = Foo::Bar->new(); 
Foo::Bar->doClassMethod(); 

que es molesto (el mismo problema se discutió en this question), especialmente ya que soy amo los métodos de la clase.

Respuesta

9

Sí, debe cambiar el nombre del package para que coincida exactamente con el del use.

+0

¿Puede ampliar un poco el significado de "tener que"? Lo pregunto porque funciona (compila y ejecuta) ** sin ** cambiar el nombre del paquete. ¿Cuáles son las consecuencias de no cambiarlo? – shawkinaw

+9

@shawkinaw Si no lo hace, el método 'import' de la declaración' use' no encontrará la clase correcta, y otros métodos de clase, incluidos los constructores, (a menudo) fallarán. Es como equivocar el caso en la declaración 'use'. Funciona en sistemas de archivos que no distinguen entre mayúsculas y minúsculas, pero solo por accidente, y todo tipo de cosas se manchan. No hagas eso. Simplemente haga su archivo, paquete y use toda la línea exactamente. Dentro de unos años, es posible que tenga algún motivo para hacer otra cosa, pero eso solo se logra con una experiencia severa y de guerra. Aún es dudoso – tchrist

+0

OK, gracias por la aclaración. – shawkinaw

1

No es estrictamente necesario (es decir, es una decisión de estilo, no es algo que el compilador impone), pero es una buena idea seguir las pautas relevantes establecidas en perlmod/perlnewmod para que el software sea fácilmente distribuible.

IOW, si le molestan los nombres largos, obtenga un editor con autocompletado.

1

Citando perldoc -f require:

si expr es un bareword, la requieren asume una extensión ".pm" y sustituye '::' con '/' en el nombre de archivo para usted, para que sea fácil de cargar módulos estándar. Esta forma de carga de módulos no implica el riesgo de de alterar su espacio de nombres. En otras palabras, si usted intenta esto:

require Foo::Bar;  # a splendid bareword 

La función requiere en realidad busca el archivo "Foo/Bar.pm" en los directorios especificados en la matriz @INC.

Así que, sí, es la convención de que si su módulo se encuentra en $dir/Foo/Bar.pm por alguna $dir en @INC, entonces debe ser llamado Foo::Bar.

2

Si cree que tener un nombre de clase Bar puede entrar en conflicto con otras clases llamadas Bar, simplemente mover el archivo no ayudará. Si su programa utiliza eventualmente Bar y Foo::Bar, ambos se habrán cargado en el mismo espacio de nombres. En ese momento, lo que le sucede a su programa es una incógnita.

Si no desea escribir nombres de clase larga, puede utilizar una variable para mantener el nombre.

use My::Long::Class::Name::For::Bar; 
my $bar_class = 'My::Long::Class::Name::For::Bar'; 

$bar_class->class_method(); # the same as My::Long::Class::Name::For::Bar->class_method() 
+0

Es cierto, pero presumiblemente no cargaría dos clases diferentes de 'Bar' al mismo tiempo. Pero veo tu punto. Sería bueno si Perl le permitiera referirse a las clases con un nombre abreviado, pero solo si no hubiera ambigüedad. Tcl, para todas sus fallas, le permite invocar procedimientos por un nombre abreviado, siempre que sea único. – shawkinaw

0

El paquete Local se reserva solo para este uso.Por ejemplo, si crea un paquete Bar.pm, puede llamar al paquete Local::Bar y saber que no entrará en conflicto con algo en CPAN.

De forma predeterminada, @INC incluye el directorio actual, por lo que puede crear un subdirectorio Local y luego colocar todos sus paquetes allí. En una empresa, dividiré el espacio de nombres del paquete Local en grupos e incluso nombres de los desarrolladores. Por ejemplo, podría usar Local::Cm::Bar o Local::David::Bar. De esa manera, si decido que puedo usar la clase Alice's Bar, simplemente podría incluir Local::Alice::Bar.

Sí, las reglas de CPAN estándar indican que no se debe usar su nombre en espacios de nombres de paquete, pero los paquetes Local nunca entran en CPAN.