argumentos perl
Perl: cómo hacer que las variables de requerir script estén disponibles en el script requerido (2)
ejemplo
out.pl:
(my|our|local|global|whatever???) var = "test";
require("inside.pm");
inside.pm:
print $var;
No quiero usar paquetes, es abrumador para mis necesidades :) ¡gracias!
Funcionará con our
.
$ cat out.pl
our $var = "test";
require("inside.pm");
$ cat inside.pm
print "Testing.../n";
print "$var/n";
$ perl out.pl
Testing...
test
Esto funciona porque our
hace $var
global, y inside.pm
se está ejecutando en el alcance con $var
definido. No estoy seguro de que sea una técnica recomendada, ¡pero de todos modos es una pregunta interesante!
EDITAR : Necesita aclarar (apruebe el parche) la respuesta basada en un comentario:
De la documentación sobre la función de Perl, our
:
our
asociados tienen un nombre simple con una variable de paquete (lectura: global) en el paquete actual, para usar dentro del alcance léxico actual. En otras palabras,our
tiene las mismas reglas de alcance quemy
ostate
, pero no necesariamente crea una variable.
Entonces, al usar our
, obtenemos $var
con el paquete actual (probablemente aquí sea el main
) y podemos usarlo en su alcance. En efecto, es entonces "global" para el código en el archivo que está requiriendo-in.
Se introduce un verdadero global sin el our
, porque las variables son por defecto globales. Pero no conozco a nadie que los recomiende.
Siempre está usando un paquete, incluso si no usa la declaración del package
. Por defecto, estás trabajando en el paquete main
.
Todas las variables que declara con our
son variables del paquete y deberían estar disponibles para todo el paquete. Aquí hay un ejemplo:
#! /usr/bin/env perl
# test2.pl
use strict;
use warnings;
our $foo = "bar";
1;
Como $foo
se declara como una variable de paquete, estará disponible en otros programas:
#! /usr/bin/env perl
use strict;
use warnings;
require "test2.pl";
our $foo;
print "The value of /$foo is $foo/n";
Ahora que te he dado suficiente cuerda, te voy a decir que no te ahorques.
Esta es una IDEA REALMENTE MAL, MALA . Tenga en cuenta que $foo
obtiene un valor de algún tipo de mecanismo misterioso que es casi imposible de descifrar.
Los paquetes son demasiado complejos ? De Verdad? ¡No es tan dificil! Mira este ejemplo:
#! /usr/bin/env perl
# test2.pm
package test2;
use strict;
use warnings;
our $foo = "bar";
1;
No es muy diferente a antes, excepto que agregué la declaración del package
y ahora llamo a mi programa test2.pm
lugar de test2.pl
.
Así es como lo accedo:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
print "The value of /$foo from package test2 is $test2::foo/n";
Todo lo que tenía que hacer era usar el nombre del paquete en la variable. Esta es una MALA IDEA , pero es mucho mejor que la REALMENTE MALA IDEA que se muestra arriba.
Al menos, ya sabes de dónde vino el valor. Vino de test2.pm
. Y, podría acceder a la variable si la configura en una subrutina.
#! /usr/bin/env perl
# test2.pm
package test2;
use strict;
use warnings;
sub fooloader {
our $foo = "bar";
}
1;
Observe que $foo
está establecido en el subprograma de subrutina. Y, aquí está mi otro programa para acceder:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
&test2::fooloader();
print "The value of /$foo from package test2 is $test2::foo/n";
Ahora, podría usar el exportador para exportar sus subrutinas (e incluso variables), pero eso ya no es algo que ya se ve demasiado. Principalmente porque es una IDEA REALMENTE MALA . No es tan malo como la IDEA REALMENTE REALMENTE MAL , pero peor que la IDEA MALA arriba:
#! /usr/bin/env perl
# test2.pm
package test2;
use base qw(Exporter);
our @EXPORT = qw(fooloader);
use strict;
use warnings;
sub fooloader {
our $foo = "bar";
}
1;
Ahora, puedo usar el subprograma de subrutina sin el nombre del paquete:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
fooloader();
print "The value of /$foo from package test2 is $test2::foo/n";
El problema, por supuesto, es que no tienes una idea real de dónde viene el fooloader
subrutinas. Si usó @EXPORT_OK
lugar de @EXPORT
, entonces podría usar use test2 qw(fooloader);
y documentar de dónde fooloader
función fooloader
. También lo ayudará a saber que no debe crear su propia función de fooloader
en su propio programa y anular la que importó. Luego, pregunte por qué su programa ya no funciona.
Por cierto, también podría exportar variables y no solo funciones. Sin embargo, eso se convierte en una IDEA REALMENTE, REALMENTE, REALMENTE MALO, NO TERRIBLE, ya que viola todas las razones por las que utiliza paquetes en primer lugar. Si vas a hacer eso, ¿para qué molestarse con los paquetes? ¿Por qué no simplemente tomar un arma y dispararse en el pie?
La mejor y preferida forma es usar Perl orientado a objetos y hacerlo de la manera CORRECTA CORRECTA . Una forma de saber exactamente qué está pasando y por qué. Y hace que sea fácil averiguar qué está haciendo tu código. Una forma de mantener los errores al mínimo.
He aquí la clase Test2 completamente orientada a objetos:
#! /usr/bin/env perl
# Test2.pm
package Test2;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub FooValue {
return "bar";
}
1;
Y usando esa clase Test2
:
#! /usr/bin/env perl
use strict;
use warnings;
use Test2;
my $tester = Test2->new;
print "The value of foo from package test2 is " . $tester->FooValue . "/n";
La razón por la cual esta es la mejor manera de hacerlo es porque incluso si usa paquetes, podría manipular el valor de $test2::foo
y se modificará en todo su programa. Imagine si esto fuera como $constants::pi
y en algún lugar lo cambiara de 3.14159 a 3. Desde entonces, usar $constants::pi
le daría el valor incorrecto. Si usa el método orientado a objetos, no podría cambiar el valor del método Constant-> Pi. Siempre será 3.14159.
Entonces, ¿qué aprendimos hoy?
Aprendimos que es muy fácil en Perl hacer algo que es REALMENTE, MALA IDEA , pero no se necesita mucho trabajo para usar paquetes, por lo que simplemente se convierte en una MALA IDEA . Y, si comienzas a aprender un poco de Perl orientado a objetos, en realidad puedes, sin demasiado esfuerzo, hacerlo todo de la manera CORRECTA CORRECTA .
La decision es tuya. Solo recuerda que el pie que disparas será probablemente el tuyo.