Re: da blocco a codice (con esempio)


#1

dimmi se mi sbaglio, ma mi sembra che in questo caso funzioni perchè
il block agisce come closure su ‘a’ che si trova esterna al blocco, ma
cade nel suo scope.

io ho bisogno di accedere ad una ‘b’ che sia stata creata per la prima
volta entro il blocko

fornisco un esempio concreto

puts get_locals {
pippo = 1234
}

dovrebbe stamparmi : “pippo: 1234”

io ho bisogno di definire get_locals.

riesco a farlo con l’inghippo di aggiungere binding alla fine… ma
vorrei toglierlo perchè fa brutto nel contesto di un DSL

puts get_locals {
pippo = 1234
binding
}

On 4/27/06, Massimiliano M. removed_email_address@domain.invalid wrote:


Chiaroscuro

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


#2

dimmi se mi sbaglio, ma mi sembra che in questo caso funzioni perchè
il block agisce come closure su ‘a’ che si trova esterna al blocco, ma
cade nel suo scope.

Funziona anche se sposti “a = 5” all’interno del blocco, lo stesso non
giova al tuo esempio purtroppo.

io ho bisogno di definire get_locals.

Un trucco c’è ma implica la rimozione dell’uguale, non so se è
accettabile nel tuo caso ma eccolo comunque.

bard@yokai:/tmp$ cat test2.rb
class Context
  def initialize
    @locals = { }
  end
  attr_reader :locals

  def method_missing(id, *args, &block)
    @locals[id] = args.first
  end
end

def get_locals(&block)
  context = Context.new
  context.instance_eval(&block)
  context.locals
end

p get_locals {
  pippo 1234
}
bard@yokai:/tmp$ ruby test2.rb
{:pippo=>1234}

Le alternative che mi vengono in mente sono sporche: usare @pippo =
123, passare a eval il sorgente del blocco con un
Kernel.local_variables alla fine, prevedere nel DSL a fine blocco un
comando “ok” o “accept” che sia alias di “binding”, sostituire
l’uguale con qualcosa di parsabile come method call (>, +, -, **,
etc)…

Massimiliano


blog: http://blog.hyperstruct.net
code: http://dev.hyperstruct.net, http://repo.hyperstruct.net


#3

giungiamo più o meno alle stesse soluzioni…

mynotsocooldsl %{
pippo = 12345
}

mynotsocooldsl <<-DSL
pippo = 12345
DSL

myabitbetterdsl do
start_stuff # questo non fa nulla
pippo = 12345
end_stuff # questo è lo sgamo che ritorna binding
end

se potessi estrarre dal blocco il nome del file e i numeri di linea…
un tocco di parsetree o di regexp potrebbe fare il lavoro sporco

On 4/27/06, Massimiliano M. removed_email_address@domain.invalid wrote:


blog: http://blog.hyperstruct.net
code: http://dev.hyperstruct.net, http://repo.hyperstruct.net


Ml mailing list
removed_email_address@domain.invalid
http://lists.ruby-it.org/mailman/listinfo/ml


Chiaroscuro

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


#4

quello che dici è vero per parametri attesi. non funziona però per
parametri inattesi… se ruby generasse un method missing sarebbe tutto
ok, ma invece decide che è una local variable.

lista_della_spesa do
uova = 3
pomodori = 2.kg, :verdi
end

devo poter gestire anche prodotti imprevisti. come il mio
fruttivendolo non deve mai dire di no davanti a richieste impossibili,
al massimo rispondere “…la settimana prossima” :wink:

On 4/27/06, Giovanni C. removed_email_address@domain.invalid wrote:


Chiaroscuro

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


#5

myabitbetterdsl do
start_stuff # questo non fa nulla
pippo = 12345
end_stuff # questo è lo sgamo che ritorna binding
end

se potessi estrarre dal blocco il nome del file e i numeri di linea…
un tocco di parsetree o di regexp potrebbe fare il lavoro sporco

Allora questo potrebbe fare al caso:

def start_stuff
  p caller.first
end

def end_stuff
  p caller.first
  Binding.of_caller { |binding| }
end

Binding.of_caller è in ruby-breakpoint.rubyforge.org.

Massimiliano


blog: http://blog.hyperstruct.net
code: http://dev.hyperstruct.net, http://repo.hyperstruct.net


#6

Il giorno gio, 27/04/2006 alle 14.09 +0200, chiaro scuro ha scritto:

dimmi se mi sbaglio, ma mi sembra che in questo caso funzioni perchè
il block agisce come closure su ‘a’ che si trova esterna al blocco, ma
cade nel suo scope.

io ho bisogno di accedere ad una ‘b’ che sia stata creata per la prima
volta entro il blocko

Posso chiedere perché? Non è più semplice usare metodi setter?

Giovanni

#7

Pare che in ZenHacks abbiano sviluppato un Proc.to_ruby…
http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/148082

On 4/27/06, Massimiliano M. removed_email_address@domain.invalid wrote:


Chiaroscuro

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


#8

questo anche funziona, ma un po me ne vergogno :wink:
riuscite a pensare a una parola alternativa al ‘the’ che stia bene sia
con ‘end’ che con ‘}’ ?

alias the binding

def lista_spesa
spesa_binding = yield

eval("local_variables", spesa_binding).each do |var|
   puts %{ * buy #{var}: #{eval "#{var}",spesa_binding }  }
end

end

lista_spesa do
pomodori = :verdi
uova = 3
the end

On 4/27/06, chiaro scuro removed_email_address@domain.invalid wrote:

se potessi estrarre dal blocco il nome del file e i numeri di linea…
Binding.of_caller { |binding| }



Chiaroscuro

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


#9
   puts %{ * buy #{var}: #{eval "#{var}",spesa_binding }  }
end

end

lista_spesa do
pomodori = :verdi
uova = 3
the end

ROTFL. Extra style bonus. Io voto per tenerlo. :smiley:


blog: http://blog.hyperstruct.net
code: http://dev.hyperstruct.net, http://repo.hyperstruct.net