Forma Lambda

Vedi tutte le pagine e le modifiche recenti o scarica i sorgenti nella pagina


Cos’e una funzione lambda o closure? Si tratta, sostanzialmente, di una funzione anonima.

Quello che fate quando usate each():

 array.each { |argomenti| codice }

in realta’ e’ equivalente a:

 def f(argomenti)
  codice
 end
 for i in array
  f(i)
 end

non e’ un caso che in ruby si possa creare una funzione anonima, cioe’ un oggetto Proc scrivendo:

oggetto= lambda {|args| codice}

Le funzioni anonime sono talmente utili che sono state introdotte in molti dei linguaggi moderni: C#, python, ruby sono degli esempi

In realtà ci sono differenze sottili, ma parliamo di come funziona in ruby. Definiamo lo scope lessicale. In pratica significa che una funzione fa riferimento a delle variabili basandosi su quello che viene definito intorno a se direttamente nel testo, e non al momento dell’esecuzione del codice.

Sembra complicato ma non lo e’, guardate:

 >> def esponenziale(num)
 >>  proc { num=num*num }
 >> end
 => nil
 >> b=esponenziale(2)
 => #<Proc:0x027d61d8@(irb):2>
 >> a=esponenziale(3)
 => #<Proc:0x027d61d8@(irb):2>
 >> a.call
 => 9
 >> b.call
 => 4
 >> a.call
 => 81
 >> a.call
 => 6561
 >> b.call
 => 16 

cosa succede? succede che l’oggetto Proc si chiude sopra alle variabili che si trovano nel suo pezzettino di codice. Non importa se poi noi usiamo altri valori (ad esempio, richiamando esponenziale() con un altro parametro.

Per le differenze vedete Closure in python

Un’altra cosa affascinante che possiamo fare con le chiusure lessicali e’ la condivisione di variabili tra diverse procedure:

 >> def add_sub(default)
 >>   return proc {default+=1},proc {default-=1}
 >> end
 => nil
 >> add,sub=add_sub(10)
 => [#<Proc:0x0275a968@(irb):25>, #<Proc:0x0275a878@(irb):25>]
 >> add
 => #<Proc:0x0275a968@(irb):25>
 >> add.call 
 => 11
 >> sub.call
 => 10
 >> sub.call
 => 9
 >> add.call
 => 10
 >> add.call
 => 11
 >> add.call
 => 12
 >> sub.call
 => 11

Ovviamente, vi starete chiedendo a cosa cavolo vi serve qesta cosa. Beh, capirete l’utilita’, forse, pensando che tra le altre cose, un blocco, cioe’ un oggetto proc, cioe’ una chiusura lessicale, e’ quello che definisce il comportamento di un Thread

 Thread.new { codice }
Updated on January 02, 2006 17:32 by Gabriele Renzi (151.37.136.250)