Cambiare il binding di un Proc?

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?


Paolo D.’
SeeSaw | Another point of view


[email protected]

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.

Giovanni

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.

On 10/13/06, Paolo Donà [email protected] wrote:

add_tab

Avete qualche idea a riguardo?


Chiaroscuro

Liquid Development: http://liquiddevelopment.blogspot.com/

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)

Paolo

On 10/13/06, Giovanni C. [email protected] wrote:


Paolo D.’
SeeSaw | Another point of view


[email protected]

eh, ma è più brutto da leggersi :slight_smile:

anche se è probabilmente + safe da cazzate che si possono fare nel
codice…

On 10/13/06, Giovanni C. [email protected] wrote:


Chiaroscuro

Liquid Development: http://liquiddevelopment.blogspot.com/

On 10/13/06, Paolo Donà [email protected] wrote:

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)

ti giro un esempio di valutazione conestuale con zia erminia e zio
ernesto
:slight_smile:

class Zio
def cook &something
puts “#{self.class.name} ha cucinato
#{self.instance_eval(&something).join
‘,’}”
end
end

class ZiaErminia < Zio
def primo
[ ‘spaghetti alla gricia’ ]
end
def secondo
[ ‘trippa alla romana’, ‘cicorietta in padella’ ]
end
end

class ZioErnesto < Zio
def primo
[ ]
end
def secondo
[ ‘polenta’, ‘salsicce’ ]
end
end

ZiaErminia.new.cook { primo + secondo }
ZioErnesto.new.cook { primo + secondo }

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’ }
?

M

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…).

Paolo

On 10/13/06, chiaro scuro [email protected] wrote:

ti giro un esempio di valutazione conestuale con zia erminia e zio ernesto
class ZiaErminia < Zio
def primo


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Paolo D.’
SeeSaw | Another point of view


[email protected]

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:

show_if { @comments.size > 3 }

che forse diventerebbe:

show_if {|ctx| ctx.instance_variable_get(:@comments).size > 3}

Che è decisamente meno bello e leggibile :frowning:

Paolo D.’
SeeSaw | Another point of view


[email protected]

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

fammi sapere se funzia, sono curioso.

On 10/13/06, Paolo Donà [email protected] wrote:

class ZioBeppe
ZiaErminia.saluta.call
Paolo

end


Paolo D.’
SeeSaw | Another point of view
http://www.seesaw.it
[email protected]


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Chiaroscuro

Liquid Development: http://liquiddevelopment.blogspot.com/

Il giorno ven, 13/10/2006 alle 13.05 +0200, Paolo Donà ha scritto:

che forse diventerebbe:

show_if {|ctx| ctx.instance_variable_get(:@comments).size > 3}

Che è decisamente meno bello e leggibile :frowning:

oppure usando un accessor:

show_if { | article | article.comments.size > 3}

Giovanni

oppure usando un accessor:
show_if { | article | article.comments.size > 3}

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.


Paolo D.’
SeeSaw | Another point of view


[email protected]

— Paolo Donà [email protected] ha scritto:

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?


icq: #69488917
blog it: http://riffraff.blogsome.com
blog en: http://www.riffraff.info


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

Scusate mi è partita la mail prima del tempo…

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 :smiley:
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


Paolo D.’
SeeSaw | Another point of view


[email protected]

On 10/13/06, Paolo Donà [email protected] wrote:

che forse diventerebbe:

show_if {|ctx| ctx.instance_variable_get(:@comments).size > 3}

Che è decisamente meno bello e leggibile :frowning:

Mah, io passerei un’oggetto ad hoc con tutti i metodi che pensi
potrebbero fare comodo per definire le condizioni :slight_smile: Per cui la
sintassi la decidi tu. Ad esempio

show_if {|ctx| ctx.get(:comments).size > 3}

o addirittura, usando method_missing:

show_if {|ctx| ctx.get_comments.size > 3}

M


http://matteo.vaccari.name

Questo è codice per un plugin pubblico… non posso prevedere cosa la
gente
userà come condizioni.

On 10/15/06, Matteo V. [email protected] wrote:

usare variabili d’istanza tipo:
potrebbero fare comodo per definire le condizioni :slight_smile: Per cui la

http://lists.ruby-it.org/mailman/listinfo/ml


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml


Paolo D.’
SeeSaw | Another point of view


[email protected]

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs