El 22 de abril de 2009 0:42, Daniel R. Troitiño
[email protected]escribió:
Por cierto, no se si el fallo es de Permalink_fu o de Rails, aunque
creo que voto por este último: es extraño tener una lista de métodos
generados cuando se supone que se generan todos a la vez, y comprobar
si la lista está vacÃa para saber si los métodos tienen que ser
generados (sobre todo teniendo en cuenta que el programador puede
modificar la lista como le apetezca). A mi parecer la comprobación
deberÃa ser atributo a atributo, pero quizá sea una optimización que
les ha salido un poco rara.
Parece la clave de todo esto la da la definición de method_missing un
poco
más abajo en el fichero:
# If we haven't generated any methods yet, generate them, then
# see if we've created the method we're looking for.
if !self.class.generated_methods?
self.class.define_attribute_methods
if self.class.generated_methods.include?(method_name)
return self.send(method_id, *args, &block)
end
end
El problema como bien comentabas es que generated_methods? es tal que:
def generated_methods?
!generated_methods.empty?
end
Con lo cual teniendo en cuenta que en ese punto generated_methods ya no
es
vacÃo sino que tiene un elemento añadido por permalink_fu,
method_missing no
llama a define_attribute_methods.
El caso es que con todo esto me ha picado la curiosidad y me ha dado por
mirar cómo resolvieron este tema la gente de paperclip, que al fin y al
cabo
también añaden métodos al modelo en el que se usa (lÃneas 161 a 172 en
la
versión 2.1.5):
define_method name do |*args|
a = attachment_for(name)
(args.length > 0) ? a.to_s(args.first) : a
end
define_method "#{name}=" do |file|
attachment_for(name).assign(file)
end
define_method "#{name}?" do
attachment_for(name).file?
end
Es decir, prescinden del uso de métodos privados de ActiveRecord y
directamente utilizan el define_method de Ruby. El caso es que viendo la
definición de evaluate_attribute_method lo único interesante que aporta
frente al define_method es que si se encuentra con un SyntaxError
continúa
con la ejecución de la aplicación, aunque eso no lo veo como una ventaja
El caso es que me gusta más el enfoque de paperclip, principalmente por
el
peligro que veo en basarte en métodos privados de una librerÃa que no
sabes
como cambiará en el futuro. En cambio, el define_method sabes que
funcionará
siempre, pasen los años que pasen (a no ser que directamente cambien
Ruby).
Ahora mis dudas son… ¿mando al autor del fork de permalink_fu que uso
un
parche implementando esa parte del código con define_method? ¿creo mi
propio
fork en github con la nueva implementación? ¿abro ticket en el
lighthouse de
rails avisando de lo que puede que le ocurra a más gente que use plugins
que
utilicen evaluate_attribute_method?
Es lo que tiene la emoción del poder aportar tu granito de arena, que no
sabes por donde empezar xD
Salu2