# Fwd: Sfida: miglior modo per generare metodi dinamicamente!

**URL:** <https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914>\
**Category:** IT\
**Created:** [June 19, 2006, 1:21pm UTC](https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914 "2006-06-19T13:21:10Z")\
**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, 1:21pm UTC](https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914/1 "2006-06-19T13:21:10Z")

</div>

> Non sarebbe meglio avere comunque un campo decimal?

Si avete ragione, nemmeno il Float va bene, dovrei tenermi il campo come  
centesimi anche dentro l’applicazione ruby, non solo a db. ma devo  
trovare  
un sitema che il to\_s mi faccia sempre la divisione e formattazione del  
numero in modo che nelle view posso sempre usare @ estimate.discount e  
anche  
gli helper dei form funzionino bene di default (cioè non voglio fare @  
estimate.discount.format\_two\_decimals).  
Ho pensato di risolvere questo riscrivendo to\_s come singleton method di  
discount ogni volta che lo leggo da DB in modo da avere un Fixnum che  
contiene i centesimi ma viene stampato correttamente (ovvero diviso per  
100)

Ho provato a farlo così ma non riesco a farlo funzionare ancora:

discount #=\> Fixnum 3334 (ovvero sconto del 33.34%)  
discount.to\_s #=\> String 3334  
discount.set\_default\_format  
discount.to\_s #=\> String 33.34 (questo è quello che voglio ottenere)

implementato  
così:  
class Fixnum  
def set\_default\_format  
class \<\< self  
def to\_s  
‘%.2f’ % self.to\_f /100  
end  
end  
end  
end

Non so perchè ma mi da un TypeError: can’t define singleton method “to\_s”  
for Fixnum  
anche se mi pare corretto…

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

Mi pare che con attr faccia casino perchè in activerecord gli attributi  
non sono attributi veri ma stanno memorizzati da qualche altra parte,  
quindi  
usando attr si incasina e qualche helper va in loop… o perlomeno  
così avevo  
letto in giro… non so di per certo, ma questo è il motivo per cui ho  
fatto  
così…

I consigli di Gabriele funzionano e sono arrivato a questo:

require ‘active\_record’  
module StoreAsCents  
def store\_as\_cents(field\_sym)  
define\_method("#{field\_sym}=") do |value|  
write\_attribute(field\_sym, (value.to\_f \* 100).to\_i)  
end

```
define_method("#{field_sym}") do
  value = read_attribute(field_sym)
  value.to_f / 100

end

```

end  
end

# includes new methods

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

Che già mi pare un pò meglio. Altri hints?

---

<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 20, 2006, 11:20am UTC](https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914/2 "2006-06-20T11:20:45Z")

</div>

for your information, ho implementato il codice che moltiplica i valori  
delle colonne in un plugin rails che si chiama store\_multiplied. Il  
plugin è  
di una banalità disarmante ma che vi posso dire, a me torna utile…  
quindi  
beccatevelo qui:  
[http://blog.seesaw.it/articles/2006/06/19/ruby-on-rails-plugin-store\_multiplied](http://blog.seesaw.it/articles/2006/06/19/ruby-on-rails-plugin-store_multiplied)

se avete idee di come risolvere meglio la questione, sono tutto orecchi,  
non  
mi dispiace per niente il fatto di sfruttare la vostra intelligenza per  
sopperire alla mia mediocrità 😃  
buona notte e un grazie di cuore per gli spunti su tutta la linea

PS: pare proprio che non si riesca a ridefinire il to\_s sulle classi  
tipo  
Float o Numeric quindi sono dovuto ricorrere a degli accessors specifici  
per  
le stringhe formattate.

Paolo

Ho provato a farlo così ma non riesco a farlo funzionare ancora:

---

<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 20, 2006, 1:03pm UTC](https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914/3 "2006-06-20T13:03:19Z")

</div>

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

> PS: pare proprio che non si riesca a ridefinire il  
> to\_s sulle classi tipo  
> Float o Numeric quindi sono dovuto ricorrere a degli  
> accessors specifici per  
> le stringhe formattate.

mi ero scordato, volevo rispondere riguardo questo…  
il problema è che non puoi definire singleton per  
float e interi perché altrimenti arriveresti a cose  
come 2+1=5 che ucciderebbero l’interprete 🙂

Però puoi definire un metodo singleton per la  
classe,usando un to\_formatted\_s o una cosa del genere,  
o wrappare to\_s per fargli prendere un argomento  
simbolico (al momento prende in input solo la base, iirc)

–  
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)

---

<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 20, 2006, 1:21pm UTC](https://www.ruby-forum.com/t/fwd-sfida-miglior-modo-per-generare-metodi-dinamicamente/95914/4 "2006-06-20T13:21:43Z")

</div>

On 6/20/06, gabriele renzi [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Però puoi definire un metodo singleton per la  
> classe,usando un to\_formatted\_s o una cosa del genere,

Grazie Gabriele, infatti in un primo momento volevo aggiungere un  
Float.to\_str.  
Il problema però è che tutti gli helper di rails e ERB invocano  
automaticamente it to\_s quindi sostazialmente o mi ridefinivo tutti gli  
helper o facevo un fake attribute formattato nei miei model che non fa  
altro  
che wrappare l’attributo persistente vero.

Praticamente ora i miei helper punteranno ad un discount\_s invece che  
discount.  
Lo so che non è molto elegante come soluzione ma non vedo alternativa…

o wrappare to\_s per fargli prendere un argomento

> simbolico (al momento prende in input solo la base, iirc)

mmm… questa non l’ho capita, me la puoi spiegare meglio? intendi fare  
un  
alias e ridefnire to\_s? tipo  
così?  
E:\prj\archeodata\>irb  
irb(main):002:0\> class Float  
irb(main):003:1\> alias :old\_to\_s :to\_s  
irb(main):004:1\> def to\_s (format = false)  
irb(main):005:2\> return “FORMATTED” if format  
irb(main):006:2\> old\_to\_s  
irb(main):007:2\> end  
irb(main):008:1\> end  
irb(main):009:0\>  
irb(main):010:0\* 12.5.to\_s #=\> “12.5”  
irb(main):011:0\> 12.5.to\_s true #=\> “FORMATTED”  
irb(main):012:0\>

Solo che non vedo come posso fare in modo che tutti gli helper mi  
chiamino  
il to\_s con un parametro…

–  
Paolo Donà  
email me: paolo[dot]dona[at]gmail[dot]com  
skype me: paolo[dot]dona
