Ciao a tutti,
Vi pongo un quesito che non sono riuscito a risolvere. Ci sono casi in
cui
mi trovo a voler valutare un blocco di codice all’interno di un contesto
di
esecuzione diverso da quello di definizione. Questo mi accade ad esempio
con
il plugin Tabnav dove faccio:
class MyTabnav < Tabnav::Base
add_tab
named ‘Pippo’
show_if “params[:pippo]==‘pluto’”
end
end
La condizione specificata in show_if ora è una stringa perchè poi ne viene
fatto un eval() all’interno della pagina che renderizza i tab.
A me però piacerebbe scrivere qualcosa tipo:
show_if {params[:pippo]==‘pluto’}
Passando a show_if un Proc invece che una stringa.
Questo perchè le condizioni potrebbero essere anche molto complesse ed è
brutto wrapparle in una stringa.
Il problema è che se faccio così alla creazione del Proc mi viene
automaticamente associato il binding della classe MyTabnav e params
viene
risolto nel contesto di MyTabnav e non della pagina rhtml.
In pratica mi servirebbe un metodo per impostare un binding arbitrario
in un
Proc prima di farne la call.
Avete qualche idea a riguardo?
Il giorno ven, 13/10/2006 alle 09.52 +0200, chiaro scuro ha scritto:
in passato ho fatto qualcosa di simile utilizzando una classe come holder di
‘contesto’.
se valuti il blocco all’interno della classe i vari nomi che utilizzi
dovrebbero venir cercati tra i metodi della classe wrappante la chiamata.
in questo modo lo stesso codice entro diversi contesti può produrre
risultati differenti.
In alternativa si potrebbe usare un blocco con un argomento.
in passato ho fatto qualcosa di simile utilizzando una classe come
holder di
‘contesto’.
se valuti il blocco all’interno della classe i vari nomi che utilizzi
dovrebbero venir cercati tra i metodi della classe wrappante la
chiamata.
in questo modo lo stesso codice entro diversi contesti può produrre
risultati differenti.
Mi fate unca esempio di come vi comportereste nel caso che ho citato?
[xChiaro] Non mi pare il Proc venga bindato nella classe che lo chiama
ma
nella classe che lo crea (nel mio caso MyTabnav)
[xGiovanni] non capisco come passare l’argomento visto che non so a
priori
che argomento devo passare (l’utente potrebbe specificare le condizioni
di
show_if in base a qualsiasi oggetto presente nella pagina rhtml)
La condizione specificata in show_if ora è una stringa perchè poi ne viene
fatto un eval() all’interno della pagina che renderizza i tab.
A me però piacerebbe scrivere qualcosa tipo:
show_if {params[:pippo]==‘pluto’}
Passando a show_if un Proc invece che una stringa.
Perché non qualcosa tipo
show_if { |context| context.params[:pippo] == ‘pluto’ }
?
Ok, i compiti per casa gli ho fatti. Ma non è quello che intendevo…
Provo a semplificare:
class ZiaErminia
def self.saluta
Proc.new {persone.each{|p| puts “ciao #{p}” }}
end
end
class ZioBeppe
def self.saluta
Proc.new { puts “Ciao a tutti” if @tempo_bello }
end
end
class Executor
def Executor.execute
persone = %w{ paolo chiaroscuro giovanni } @tempo_bello = true
ZiaErminia.saluta.call
ZioBeppe.saluta.call
end
end
Executor.execute
Voglio che in qualche modo i Proc utilizzino il binding di Executor e
non
della classe dove vengono definiti (Ovviamente il codice che ho postato
canna…).
Perché non qualcosa tipo show_if { |context| context.params[:pippo] ==
‘pluto’} ?
Questa soluzione mi piace. Che oggetto passeresti tu come context? il
self
della pagina .rhtml? stavo pensando però come viene nel caso uno voglia
usare variabili d’istanza tipo:
mmmhh dovresti riuscire a passare a saluta() il contesto chiamante e poi
(come da mio esempio precedente) eseguira la proc con instance_eval su
quel
contesto.
il contesto lo puoi passare esplicitamente come extra parametro self,
oppure
implicitamente tracciando il caller (eseguire self nel binding dato da
binding_of_caller?)
La condizione è generica, non posso avere argomenti diversi in input di
volta in volta.
La pagina rhtml cicla i vari tab e valuta la condizione passando self (o
il
binding) quindi un parametro specifico come article non va bene.
Ciao a tutti,
Vi pongo un quesito che non sono riuscito a
risolvere. Ci sono casi in cui
mi trovo a voler valutare un blocco di codice
all’interno di un contesto di
esecuzione diverso da quello di definizione.
Proc#rebind è una RCR vecchissima. Non va bene fare
solo un instance_eval &proc?
Do You Yahoo!?
Poco spazio e tanto spam? Yahoo! Mail ti protegge dallo spam e ti da
tanto spazio gratuito per i tuoi file e i messaggi http://mail.yahoo.it
Nel mio l’Executor sarà la pagina rhtml e il ProcContainer sarà la
definizione del Tab. Unica cosa probabilmente ribalto la frittata
iniettando
la pag nel tab in modo da avere qualcosa tipo:
class ProcContainer
def self.pr
Proc.new { @ducks }
end
def self.result(page)
page.instance_eval &pr
end
end
class Executor
def execute @ducks = %w{ qui quo qua}
ProcContainer.result self
end
end
Appena lo migro nel plugin vi faccio sapere come è andata
Paolo
Proc#rebind è una RCR vecchissima. Non va bene fare
solo un instance_eval &proc?
Si funziona, questa è la vesione semplificata.
class ProcContainer
def self.pr
Proc.new { @ducks }
end
end
class Executor
def execute @ducks = %w{ qui quo qua}
instance_eval &ProcContainer.pr
end
end
puts Executor.new.execute.inspect
Nel mio l’Executor sarà la pagina rhtml e il ProcContainer sarà la
definizione del Tab. Unica cosa probabilmente ribalto la frittata
iniettando
la pag nel tab in modo da avere qualcosa tipo:
class ProcContainer
def self.pr
Proc.new { @ducks }
end
def result(page)
end
end
class Executor
def execute @ducks = %w{ qui quo qua}
instance_eval &ProcContainer.pr
end
end
Mah, io passerei un’oggetto ad hoc con tutti i metodi che pensi
potrebbero fare comodo per definire le condizioni Per cui la
sintassi la decidi tu. Ad esempio