Buscar..


Observaciones

Las subrutinas llevan sus argumentos a la variable mágica llamada @_ . Si bien no tiene que desempaquetarse, se recomienda, ya que ayuda a la legibilidad y evita cambios accidentales a medida que los argumentos de @_ se pasan por referencia (se pueden modificar).

Creando subrutinas

Las subrutinas se crean utilizando la palabra clave sub seguido de un identificador y un bloque de código entre llaves.

Puede acceder a los argumentos utilizando la variable especial @_ , que contiene todos los argumentos como una matriz.

sub function_name {
    my ($arg1, $arg2, @more_args) = @_;
    # ...
}

Como la función shift predeterminada a desplazar @_ cuando se usa dentro de una subrutina, es un patrón común extraer los argumentos de forma secuencial en variables locales al comienzo de una subrutina:

sub function_name {
    my $arg1 = shift;
    my $arg2 = shift;
    my @more_args = @_;
    # ...
}

# emulate named parameters (instead of positional)
sub function_name {
    my %args = (arg1 => 'default', @_);
    my $arg1 = delete $args{arg1};
    my $arg2 = delete $args{arg2};
    # ...
}

sub {
    my $arg1 = shift;
    # ...
}->($arg);
5.20.0

Alternativamente, la característica experimental "signatures" puede usarse para desempaquetar parámetros, que se pasan por valor ( no por referencia).

use feature "signatures";

sub function_name($arg1, $arg2, @more_args) {
    # ...
}

Los valores por defecto se pueden utilizar para los parámetros.

use feature "signatures";

sub function_name($arg1=1, $arg2=2) {
    # ...
}

Puede usar cualquier expresión para asignar un valor predeterminado a un parámetro, incluidos otros parámetros.

sub function_name($arg1=1, $arg2=$arg1+1) {
    # ...
}

Tenga en cuenta que no puede hacer referencia a los parámetros que se definen después del parámetro actual; por lo tanto, el siguiente código no funciona como se esperaba.

sub function_name($arg1=$arg2, $arg2=1) {
    print $arg1;  # => <nothing>
    print $arg2;  # => 1
}

Los argumentos de subrutina se pasan por referencia (excepto los de las firmas)

Los argumentos de subrutina en Perl se pasan por referencia, a menos que estén en la firma. Esto significa que los miembros de la matriz @_ dentro del subgrupo son solo alias de los argumentos reales. En el siguiente ejemplo, $text en el programa principal se deja modificado después de la llamada de subrutina porque $_[0] dentro del sub es en realidad solo un nombre diferente para la misma variable. La segunda invocación genera un error porque un literal de cadena no es una variable y, por lo tanto, no se puede modificar.

use feature 'say';

sub edit {
    $_[0] =~ s/world/sub/;
}

my $text = "Hello, world!";
edit($text);
say $text;      # Hello, sub!

edit("Hello, world!"); # Error: Modification of a read-only value attempted

Para evitar obstruir las variables de su interlocutor, por lo tanto, es importante copiar @_ a las variables de ámbito local ( my ... ) como se describe en "Crear subrutinas".

Subrutinas

Código de espera de subrutinas. A menos que se especifique lo contrario, se definen globalmente.

# Functions do not (have to) specify their argument list
sub returns_one {
  # Functions return the value of the last expression by default
  # The return keyword here is unnecessary, but helps readability.
  return 1;
}

# Its arguments are available in @_, however
sub sum {
  my $ret = 0;
  for my $value (@_) {
    $ret += $value
  }
  return $ret;
}

# Perl makes an effort to make parens around argument list optional
say sum 1..3;     # 6

# If you treat functions as variables, the & sigil is mandatory.
say defined &sum; # 1

Algunas incorporaciones como print o say son palabras clave, no funciones, por lo que, por ejemplo, &say no está definido. También significa que puede definirlos, pero tendrá que especificar el nombre del paquete para llamarlos

# This defines the function under the default package, 'main'
sub say {
  # This is instead the say keyword
  say "I say, @_";
}

# ...so you can call it like this: 
main::say('wow'); # I say, wow.
5.18.0

Desde Perl 5.18, también puede tener funciones no globales:

use feature 'lexical_subs';
my $value;
{
  # Nasty code ahead
  my sub prod {
    my $ret = 1;
    $ret *= $_ for @_;
    $ret;
  }
  $value = prod 1..6; # 720 
  say defined &prod; # 1
}
say defined &prod; # 0
5.20.0

Desde 5.20, también puede tener parámetros con nombre.

use feature 'signatures';
sub greet($name) {
  say "Hello, $name";
}

Esto no debe confundirse con los prototipos, una instalación que Perl tiene para permitirle definir funciones que se comportan como integradas. Los prototipos de funciones deben ser visibles en el momento de la compilación y sus efectos pueden ignorarse especificando el & sigil. Los prototipos generalmente se consideran una característica avanzada que se utiliza mejor con gran cuidado.

# This prototype makes it a compilation error to call this function with anything 
# that isn't an array. Additionally, arrays are automatically turned into arrayrefs
sub receives_arrayrefs(\@\@) {
   my $x = shift;
   my $y = shift;
}

my @a = (1..3);
my @b = (1..4);
receives_arrayrefs(@a, @b);    # okay,   $x = \@a, $y = \@b, @_ = ();
receives_arrayrefs(\@a, \@b);  # compilation error, "Type … must be array …"
BEGIN { receives_arrayrefs(\@a, \@b); }

# Specify the sigil to ignore the prototypes. 
&receives_arrayrefs(\@a, \@b); # okay,   $x = \@a, $y = \@b, @_ = ();
&receives_arrayrefs(@a, @b);   # ok, but $x = 1,   $y = 2,   @_ = (3,1,2,3,4);


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow