Decir que tengo un paquete llamado My::Pkg
, y que el paquete tiene un método ->new(...)
clase para crear instancias de objetos nuevos:En Perl, ¿hay algún daño al crear una subrutina con el mismo nombre que un paquete?
package My::Pkg;
sub new {bless {@_[1..$#_]} => $_[0]}
¿Hay algún daño en la definición de la siguiente subrutina:
sub My::Pkg {@_ ? My::Pkg::new('My::Pkg', @_) : 'My::Pkg'}
Así que alguien podría escribir:
my $obj = My::Pkg one => 1, two => 2;
En lugar de:
my $obj = My::Pkg->new(one => 1, two => 2); # which still works, but is longer
Me gusta la concisión del método package-named-constructor-subroutine, pero me interesa saber si hay algún truco escondido en esta técnica que no haya pensado.
Actualización:
herencia funciona correctamente, como se muestra en el ejemplo aquí:
{package a; sub new {say "a::new [@_] ", $_[0]->init}}
{package b; our @ISA = 'a'; sub init {"(b::init [@_])"}}
{package a::b; our @ISA = 'b';}
sub a::b {print "absub [@_], "; 'a::b'}
# a::b() called with no args, returns 'a::b', which then becomes 'a::b'->new(...)
a::b->new; # absub [], a::new [a::b] (b::init [a::b])
a::b->new(1, 2, 3); # absub [], a::new [a::b 1 2 3] (b::init [a::b])
# no call to `a::b()` but otherwise the same:
'a::b'->new; # a::new [a::b] (b::init [a::b])
'a::b'->new(1, 2, 3); # a::new [a::b 1 2 3] (b::init [a::b])
new a::b::; # a::new [a::b] (b::init [a::b])
new a::b:: 1, 2, 3; # a::new [a::b 1 2 3] (b::init [a::b])
Curiosamente el único hasta ahora que es diferente es que los 2 siguientes líneas se convierten en errores de sintaxis:
new a::b;
new a::b 1, 2, 3;
¿Qué es un error de sintaxis por la misma razón some_undefined_sub some_defined_sub;
es uno.
Si se define la subrutina new
, se analiza como new(a::b(...))
, lo que es normal para dos subrutinas de palabra abierta adyacentes.
Personalmente, estoy bien con new a::b
convertirse en un error de sintaxis, la versión sin ambigüedades new a::b::
siempre funcionará como tchrist señala amablemente a continuación.
Parece limpio. Si algo fallara, sería 'some_sub My :: Pkg a => 1, b => 2;'. No es así – ikegami
@ikegami: Ciertamente ** NO ** falla: 'sub X :: Y {morir" X :: Y() llamado \ n "} sub X :: Y :: nuevo {advertir" X :: Y :: new() llamado \ n "} sub nuevo {die" main :: new() called "} $ a = new X :: Y" business "; warn "got $ a"; 'morirá porque llama a' main :: new (X :: Y ("business")) 'como una subrutina en lugar de invocar apropiadamente' X :: Y :: new ("X: : Y "," business "))' como un método. Además, la llamada a la subrutina no respeta la herencia, ya que se considera obligatoria en un mundo OO. – tchrist
Es malo que 'nuevo negocio X :: Y" 'repentinamente signifique algo diferente de' X :: Y-> nuevo ("negocio") '- * que * BTW actualmente significa' X :: Y() - > nuevo ("negocio") 'en lugar de' X :: Y :: nuevo ("X :: Y", "negocio") 'que todos piensan que significa. – tchrist