Skip to content

Latest commit

 

History

History
90 lines (64 loc) · 3.06 KB

16-programaciondinamica.md

File metadata and controls

90 lines (64 loc) · 3.06 KB

Programación Dinámica

Ya he mencionado al comienzo que Ruby es un lenguaje dinámico. Pero ¿qué es lo que consideramos como lenguaje dinámico?

Bueno, por una parte, Ruby es un lenguaje dinámicamente tipado. Las variables y métodos no tienen tipo, sino que los valores que albergan y devuelven son los que son objetos de alguna clase. No hay variables string o enteras, sino valores string y valores enteros. Lenguajes estáticamente tipados son Java y C#.

Pero también Ruby es dinámico porque puede:

  • Evaluar expresiones que se calculan u obtienen en ejecución, en lugar de estar determinadas al momento de lanzar el programa
  • Modificar el propio programa en ejecución

Programas Automodificables

Una cosa es escribir un programa, y otra es ejecutarlo. En los lenguajes compilados, todo el código a ejecutar queda definido al escribirlo y compilarlo. Pero la mayoría de los lenguajes interpretados permite evaluar código creado en el momento.

El Gran eval

Esta función ya definida en Ruby nos permite tomar un string y evaluarlo como código Ruby. Por ejemplo, podemos pedir una línea por consola y evaluarla como expresión Ruby, si es válida:

expresion = gets.chomp
eval(expresion)

Esto abre la puerta para que podamos, por ejemplo, tomar expresiones de campos de una base de datos, y evaluarlas dinámica en nuestro programa. Y si lo que evaluamos implica definir un método, una clase, u otro elemento de programación Ruby, estaremos modificando el programa en ejecución. Ejemplo:

eval('def foo; puts "foo"; end')

define un nuevo método foo que podemos invocar de ahora en más.

Otros Tipos de eval

(A completar: instance_eval, class_eval, module_eval)

Definiendo un Método Dinámicamente

Supongamos que tenemos que definir una clase Semaforo con un estado interno que se puede modificar por métodos:

class Semaforo
    def rojo
        @estado = :rojo
    end
    
    def verde
        @estado = :verde
    end
    
    def amarillo
        @estado = :amarillo
    end
end

Acá fueron tres estados, pero podrían ser más. Hay otra forma de definir un método, usando define_method que espera dos parámetros: un símbolo con el nombre del método a definir, y un bloque que sea el cuerpo del método. Veamos:

class Semaforo
    [:rojo, :verde, :amarillo].each do |nombre|
        define_method nombre do
            @estado = nombre
        end
    end
end

(A completar)

Fuentes Consultadas