Si Rails no es multihilo entonces...
Publicado por el Sábado, 02 de Febrero de 2008
...podemos olvidarnos de algunas costumbres adquiridas con otras plataformas (léase J2EE o .NET) y aprovechar ciertas construcciones de Ruby que en un entorno multihilo sería problemático usar libremente. ¿A qué me refiero?, a variables de clase.
Las amigables variables de clase almacenan valores compartidos por todas las instancias de dicha clase, y a estas alturas todos deberíamos saber que si más de un hilo puede leer/modificar una de estas variables, tenemos que gestionar la concurrencia. No obstante, el caso de Rails es diferente. Podemos asegurar que cada instancia de nuestro servidor (normalmente un mongrel) sólo va a ejecutar un hilo por cada petición y por tanto podemos utilizar las variables de clase impunemente.
Supongamos, como ejemplo, una página que muestra varios valores monetarios sujetos a tipo de cambio. Supongamos el siguiente código que gestiona ésto (sin entrar a discutir si es adecuado o 100% correcto, que no lo es, ya lo sé, pero para ilustrar la idea vale).
class Currency
TYPES = %w(euro dollar)
attr_accessor :value
def initialize(value)
self.value = value
end
def to
Exchange.new self
end
alias :in :to
end
class Dollar < Currency
def to_s
"#{value}$"
end
end
class Euro < Currency
def to_s
"#{value}€"
end
end
class Exchange
cattr_accessor :rates
def initialize(currency)
@currency = currency
end
for currency in Currency::TYPES
class_eval %{
def #{currency}
rate = self.class.rates[:#{currency}][@currency.class.name.downcase]
#{currency.classify}.new @currency.value * rate
end
alias :#{currency.pluralize} :#{currency}
}
end
end
class Fixnum
for currency in Currency::TYPES
class_eval %{
def #{currency}
#{currency.capitalize}.new self
end
alias :#{currency.pluralize} :#{currency}
}
end
end
De tal modo que, para cada petición sólo es necesario fijar una vez las tipos de cambio, usando para ello un before_filter ...
def exchange_rates_set_before_filter
# ... Lógica real para obtener los tipos de cambio ...
Exchange.rates = HashWithIndifferentAccess.new({
:dollar => {
:dollar => 1,
:euro => 1.49
},
:euro => {
:euro => 1,
:dollar => 0.67
}
})
Y así poder escribir en nuestras vistas cosas sencillas y elegantes como:
1.dollar.in.euros #=> 0.67€ 2.euros.in.dollars #=> 2.98$

Tu comentario