Tutorial de Ruby – Parte 25 – Variables locales

Una variable local tiene un nombre que empieza con una letra minúscula o con el carácter de subrayado (_). Las variables locales no tienen, a diferencia de las variables globales y las variables de instancia, el valor nil antes de la inicialización:

 

ruby> $foo

nil

ruby> @foo

nil

ruby> foo

ERR: (eval):1: undefined local variable or method ‘foo’ for #<Object:0x401d2c90>

 

La primera asignación que se realiza sobre una variable local actúa como una declaración. Si se referencia a una variable local no inicializada, el intérprete de Ruby piensa que se trata de una llamada a un método con ese nombre; de ahí el mensaje de error del ejemplo anterior.

 

Generalmente el ámbito de una variable local es uno de los siguientes:

  • proc{ … }
  • loop{ … }
  • def … end
  • class … end
  • module … end
  • Todo el programa (si no es aplicable ninguno de los puntos anteriores)

 

En el siguiente ejemplo define? es un operador que verifica si un identificador está definido. Si lo está, devuelve una descripción del mismo, en caso contrario, devuelve nil. Como se ve el ámbito de bar es local al bucle, cuando se sale del bucle, bar está sin definir.

 

ruby> foo =44; print foo, «\n»; defined? foo

44

«local-variable»

ruby> loop{bar = 45;print bar, «\n»; break}; defined? var

45

nil

 

Los objetos procedimiento que residen en el mismo ámbito comparten las variables locales que pertenecen a ese ámbito. En el siguiente ejemplo, la variable bar es compartida por main y los objetos procedimiento p1 y p2:

 

ruby> bar=0

0

ruby> p1 = proc{|n| bar = n}

#<Proc:0x401c3e34>

ruby> p2 = proc{bar}

#<Proc:0x401c3cf4>

ruby> p1.call(5)

5

ruby> bar

5

ruby> p2.call

5

 

Obsérvese que no se puede omitir la línea bar=0 inicial; esta asignación es la que garantiza que el ámbito de bar incluirá a p1 y p2. Si no, p1 y p2 tendrán al final cada uno su propia variable local bar y la llamada a p2 dará lugar a un error de “variable o método no definido”.

 

Una característica muy poderosa de los objetos procedimiento se deriva de su capacidad para recibir argumentos; las variables locales compartidas permanecen válidas incluso cuando se las pasa fuera de su ámbito original.

 

ruby> def box

ruby| contents = 15

ruby| get = proc{contents}

ruby| set = proc{|n| contents = n}

ruby| return get, set

ruby| end

nil

ruby> reader, writer = box

[#<Proc:0x401c33d0>, #<Proc:0x401c33bc>]

ruby> reader.call

15

ruby> writer.call(2)

2

ruby> reader.call

2

 

Ruby es especialmente inteligente con respecto al ámbito. En el ejemplo, es evidente que la variable contents está compartida por reader y writer. Ahora bien, es posible definir varios pares reader-writer que utilicen box cada uno de los cuales comparten su propia variable contents sin interferir uno con otro.

 

ruby> reader_1, writer_1 = box

[#<Proc:0x401c2e6c>, #<Proc:0x401c2e58>]

ruby> reader_2, writer_2 = box

[#<Proc:0x401c2cdc>, #<Proc:0x401c2cc8>]

ruby> writer_1.call(99)

99

ruby> reader_1.call

99

ruby> reader_2.call

15

 

Gus Terrera

Apasionado por el agile testing y la ia.

Deja una respuesta