Tou tentando criar umas classes programaticamente pra embonitar uma DSL que eu quero fazer:
moduleProductsenddefproduct(name)Products.const_setname,Class.newdo|c|defto_s"I am a #{name}"endendendproduct:BananaputsProducts::Banana.to_s,Products::Banana.new.to_s
def constantize
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
end
Object.module_eval("::#{self}",__FILE__,__LINE__)
end
end
moduleProducts
end
defproduct(name)
eval(“class#{name};end”)
new_class=name.to_s.constantize
Products.const_setname,new_class
end
product:Banana
moduleDynamicModule
defto_s
"Iama#{<ahref="http://self.class.name">self.class.name</a>}"
end
end
Products::Banana.send(:include,DynamicModule)
putsProducts::Banana.to_s,Products::Banana.new.to_s
Imprime:
Banana
I am a Banana
Realmente ou é um ou é outro, não tem como ser os dois
cv1
Valeu, Mauricio!
Achei outro jeito, tambem:
defproduct(name,pricing_proc)c=Class.newdoattr_reader:quantitydefinitialize(quantity=1)@quantity=quantityendendc.class_evaldodefine_method:price,pricing_procdefine_method:to_sdo"I am a #{name}"endendProducts.const_setname,cendincludeProductsproduct:BananaputsBanana.to_s,Banana.new.to_s
Mauricio_Linhares
Ainda sobre o WTF, o problema não é que naquela primeira definição o método está sendo definido na instância de Class não?
cv1
Nao… na verdade, a versao inicial tem dois problemas:
o bloco tava sendo passado pro const_set ao inves do Class.new (o que eh um problema bem sutil, foi foda diagnosticar)
codigo dentro de def, class e module nao pode usar variaveis que estao fora dele, caso a coisa esteja acontecendo num bloco. O Ola me explicou, e eu juro que entendi na hora, mas nao consigo explicar direito (e tambem nao sei nem se eu entendi tao bem assim). Se alguem souber de um be-a-bá sobre isso, ia ser bem-vindo
Emerson_Macedo
Cara, quanto ao item “1)” do que você falou, juro que tinha pensado nisso assim que li a thread mas como tava sem tempo não fuxiquei pra ter certeza. Realmente é ruim de diagnosticar pois a tendência é achar que está sendo passado para o Class.new mesmo.