# Sfida: miglior modo per generare metodi dinamicamente!

**URL:** <https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793>\
**Category:** IT\
**Created:** [June 19, 2006, 11:13am UTC](https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793 "2006-06-19T11:13:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paolo\_DonSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/898d66/32.png) [@Paolo\_DonSSSS](https://www.ruby-forum.com/u/Paolo_DonSSSS)\
**Post date:** [June 19, 2006, 11:13am UTC](https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793/1 "2006-06-19T11:13:30Z")

</div>

Ciao a tutti,  
Ho appena fatto un banalissimo plugin per rails, e mi ha scatenato il  
dubbio  
che io non stia facendo nel modo migliore la generazione automatica di  
metodi in ruby… ok, mi spiego meglio (non è necessaria la conoscenza di  
rails per godersi il post)  
Per questo vi sfido (per gioco ovvio, visto che so di perdere:-)) a  
trovare  
una soluzione migliore…

Ho un oggetto che mi rappresenta un record di stima di un preventivo,  
nel  
quale devo salvare un campo discount che è un Float (lo sconto deve avere  
2  
decimali).  
Io NON voglio salvare il float a DB ma voglio moltiplicarlo e dividerlo  
per  
100 ogni volta che lo salvo/leggo da db, in pratica lo salvo in  
centesimi.  
La cosa si fa così, da documentazione di rails:

class Estimate \< ActiveRecord::Base  
def discount=(value)  
write\_attribute(:discount, value \* 100)  
end

def discount  
read\_attribute(:discount) / 100  
end  
end

(soprassediamo sul fatto che non converte a float, ma non è quello il  
punto)  
Il problema è che io potrei avere 200 campi che voglio salvare in questo  
modo, quindi con il sopracitato plugin voglio convertire il codice in:

class Estimate \< ActiveRecord::Base  
store\_as\_cents :discount  
end

A questo punto parte la sfida: devo definire il metodo store\_as\_cents in  
modo che mi crei in modo dinamico i getter e i setter.  
Ho implementato il plugin come modulo in modo da mixare  
store\_as\_centsinvece che ‘aprire’ la classe  
ActiveRecord::Base, mi pare una soluzione più pulita e meno invasiva, ma per  
qualche motivo ho la sensazione che si possa fare di meglio.

Di seguito la mia soluzione:

require ‘active\_record’  
module StoreAsCents  
def self.included(mod)  
mod.extend(ClassMethods)  
end

module ClassMethods  
# dinamically creates  
# getters and setter that divide or multiply by 100  
def store\_as\_cents(field\_sym)  
methods = \<\<-EOF  
def #{field\_sym}=(value)  
write\_attribute(:#{field\_sym}, value \* 100)  
end

```
    def #{field_sym}
      read_attribute(:#{field_sym}) / 100
    end
  EOF
  class_eval methods
end

```

end  
end

# includes new methods

ActiveRecord::Base.class\_eval do  
include StoreAsCents  
end

Mi pare contorto il fatto di dovere includere il modulo e poi dire al  
modulo  
che quando è incluso la classe deve estendere un’altro modulo interno e  
bla  
bla… ma così viene fatto nei plugins di rails che ho visto in giro…  
Gabriele ormai mi ha convinto che rails fa schifo, quindi ora dobbiamo  
trovare un modo migliore di fare sta cosa for god’s sake!!

Il per sempre vostro kamikaze,  
Paolo

---

<div class="post-metadata">

**Author:** ![Paolo\_DonSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/898d66/32.png) [@Paolo\_DonSSSS](https://www.ruby-forum.com/u/Paolo_DonSSSS)\
**Post date:** [June 19, 2006, 11:34am UTC](https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793/2 "2006-06-19T11:34:35Z")

</div>

Ciao  
premesso che non so nulla di ruby  
dal punto di design , l’attributo discount non dovrebbe essere un tipo  
“semplice” (ho scritto una cosa sbagliata ma si dovrebbe capire il  
senso) ma  
di una classe di tipo currency  
e questa potrebbe avere i setter e i getter.

Ci sono un paio di aspetti da considerare funzionalmente

- le logiche amministrative/fiscali per la gestione degli arrotondamenti
- la somma di n prezzi arrotondati è diversa dalla somma arrontondata  
trovo strano delegare le logiche di arrotondamento al db

ma probabilmente il senso della domanda era tutt’altro  
non appena imparerò qualcosa di puù di Ruby potrò essere più d’aiuto.  
Ciao Paolo

---

<div class="post-metadata">

**Author:** ![Paolo\_DonSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/898d66/32.png) [@Paolo\_DonSSSS](https://www.ruby-forum.com/u/Paolo_DonSSSS)\
**Post date:** [June 19, 2006, 11:40am UTC](https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793/3 "2006-06-19T11:40:36Z")

</div>

2006/6/19, Paolo Donà [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Per questo vi sfido (per gioco ovvio, visto che so di perdere:-)) a trovare  
> una soluzione migliore…

Manca un’informazione fondamentale: la posta  
😛

Michele

---

<div class="post-metadata">

**Author:** ![Paolo\_DonSSSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/898d66/32.png) [@Paolo\_DonSSSS](https://www.ruby-forum.com/u/Paolo_DonSSSS)\
**Post date:** [June 19, 2006, 12:08pm UTC](https://www.ruby-forum.com/t/sfida-miglior-modo-per-generare-metodi-dinamicamente/63793/4 "2006-06-19T12:08:04Z")

</div>

— Paolo Donà [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha scritto:

> Ho un oggetto che mi rappresenta un record di stima  
> di un preventivo, nel  
> quale devo salvare un campo discount che è un Float  
> (lo sconto deve avere 2  
> decimali).

Non sarebbe meglio avere comunque un campo decimal ?  
Mia mamma mi ha detto di non mettere insieme float e  
soldi 🙂

> Io NON voglio salvare il float a DB ma voglio  
> moltiplicarlo e dividerlo per  
> 100 ogni volta che lo salvo/leggo da db, in pratica  
> lo salvo in centesimi.

ok

> end  
> io avrei usato una coppia di accessor da ruby (con  
> attr) e poi inserito una regola before\_save, ma così è  
> effettivamente più consistente 🙂

\> # getters and setter that divide or multiply by \> end \> \> Mi pare contorto il fatto di dovere includere il \> modulo e poi dire al modulo \> che quando è incluso la classe deve estendere \> un'altro modulo interno e bla \> bla... 

concordo, _è_ contorto, l’approccio di abusare  
included è utile se devi mixare delle funzionalità sia  
a livello di istanza che di classe, credo.  
Nel tuo caso sarebbe più semplice mettere il modulo  
direttamente nella classe tramite #extend, penso.

D’altronde penso che potresti levare la stringa ed il  
class\_eval e mettere semplicemente

define\_method field\_sym {code}  
define\_method “#{field\_sym}=” {code2}

> ma così viene fatto nei plugins di rails che  
> ho visto in giro…

dicevo l’altro giono a giovanni corriga che rails ha  
effetti deleteri sulla comunità degli sviluppatori per  
quel che riguarda l’abuso di  
\*eval/extend/include/singleton class.

> Gabriele ormai mi ha convinto che rails fa schifo,  
> quindi ora dobbiamo  
> trovare un modo migliore di fare sta cosa for god’s  
> sake!!

oh mio dio cosa ho fatto! [cit]

–  
icq: #69488917  
blog it: [http://riffraff.blogsome.com](http://riffraff.blogsome.com)  
blog en: [http://www.riffraff.info](http://www.riffraff.info)

Chiacchiera con i tuoi amici in tempo reale!  
[Yahoo Search - Ricerca nel Web | Motore di Ricerca](http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com)
