Perl – Función de cierre

El cierre es uno de los conceptos importantes en Perl . Cierre es un término informático con un significado preciso pero difícil de explicar. A menudo se la conoce como una función que se puede almacenar como una variable, que tiene una capacidad especial para acceder a otras variables locales del ámbito en el que se creó. Se usa para referirse a cualquiera de las variables locales de la función externa y cuando el compilador detecta eso, mueve estas variables a la declaración de objetos ocultos del cierre desde el espacio de pila de la función exterior. Luego genera una variable de tipo cierre.
Así que, básicamente, una función que captura el entorno léxico en el que se crea, es decir, recorre recopilando todas las cosas del entorno en ese momento, se conoce como función de cierre.

El cierre con respecto al lenguaje Perl significa que: la subrutina 1 devuelve alguna otra subrutina 2, luego la subrutina 2 accede a la variable x presente en la subrutina 1 y cuando finaliza la ejecución de la subrutina 1, el usuario ya no puede acceder a x, sino a la subrutina 2 porque también se refiere a la variable x que apunta al objeto de datos. Hace que la subrutina 2 continúe accediendo a este objeto de datos después del final de la subrutina 1.
Por lo tanto, la variable x en la subrutina 1 debe ser una variable léxica, de lo contrario, después de la ejecución de la subrutina 1, la variable x aún puede ser accedida por el exterior. mundo, modificar, si es así, el cierre y la función normal no tiene sentido.

Un cierre es un tipo de función que está vinculada a un entorno determinado y se escribe como una función dentro de otra función.

Ejemplo:

sub make_adder 
{
    my $addpiece = shift;
    return sub { shift() + $addpiece };
}
  
# Driver Code
my $f1 = make_adder(555);
my $f2 = make_adder(20);

Ahora $f1($n) siempre es 555 más cualquier $n que ingrese, mientras que $f2($n) siempre es 20 más cualquier $n que ingrese. El $addpiece en el cierre permanece.

Usos de los Cierres

Los cierres son cosas realmente útiles. Por ejemplo, para las devoluciones de llamada, en lugar de pasar un puntero de función de devolución de llamada + argumento en una función, y tener que calcular en esa función con qué te han devuelto la llamada, uno puede simplemente usar un cierre. Cuando se llama a esa función, tiene acceso a todo el entorno léxico de cuando se creó.

Algunos de los usos principales del cierre son: usarlos como devolución de llamada ‘inteligente’ y el otro es usarlos como iteradores.

  • Función de devolución de llamada inteligente
    Por ejemplo: Queremos crear un botón (usando el kit de herramientas Tk) dándole una referencia de subrutina. Pero será un problema si queremos dar una subrutina a 2 botones diferentes en la pantalla. Por lo tanto, para hacer eso, usaremos una rutina de devolución de llamada ‘inteligente’, es decir, un cierre. Esto hará que el cierre almacene algunos datos que son específicos de ese botón (como su nombre) y cuando se llama a esa subrutina, le da acceso a esos datos.
  • Iteradores
    Un iterador suele ser una referencia de código que, cuando se ejecuta, calcula el siguiente elemento de una lista y lo devuelve.
    Por ejemplo: considere que hay una secuencia de números pares y tiene un iterador que devuelve el siguiente número par cada vez que se llama. Claramente, no es posible generar todos los números pares posibles, pero siempre puede calcular el siguiente número par si recuerda el número anterior generado. El iterador recuerda esta información crucial.
  • Otro uso del cierre es que puede hacer que una variable sea privada para una subrutina nombrada.
    Por ejemplo: un contador que se inicializa en el momento de la creación del sub y solo se puede modificar desde dentro del sub. Esto se puede usar a veces con un bloque BEGIN en los archivos del paquete para asegurarse de que una variable no interfiera durante la vida útil del paquete.

Uso de la aplicación parcial

La función de aplicación parcial se conoce como la capacidad de tomar una función que tiene muchos parámetros y aplicar argumentos a algunos de esos parámetros para crear una nueva función que requiere la aplicación de solo los argumentos restantes para producir el equivalente de aplicar los argumentos a la función original.
La característica recurrente de la aplicación parcial es que cuando se aplica a un parámetro, se supone que otros parámetros no deben mencionarse explícitamente.

Ejemplo:

sub fs(&) 
{ 
    my $func = shift;
    sub { map $func->($_), @_ }
}
    
sub double($) { shift() * 2 }
sub square($) { shift() ** 2 }
    
my $fs_square = fs(\&square);
my $fs_double = fs(\&double);
    
my @s = 0 .. 3;
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";
    
@s = (2, 4, 6, 8);
print "fs_square(@s): @{[ $fs_square->(@s) ]}\n";
print "fs_double(@s): @{[ $fs_double->(@s) ]}\n";

Producción:

fs_square(0 1 2 3): 0 1 4 9
fs_double(0 1 2 3): 0 2 4 6
fs_square(2 4 6 8): 4 16 36 64
fs_double(2 4 6 8): 4 8 12 16

Publicación traducida automáticamente

Artículo escrito por vishalraina y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *