Cosa possono fare procs e lambda che le funzioni non possono in ruby

5

Ho lavorato in Ruby per le ultime due settimane e sono arrivato al tema di procs, lambda e blocchi. Dopo aver letto una buona dose di esempi da una varietà di fonti, non so come siano molto diverse dalle funzioni piccole e specializzate. È del tutto possibile che gli esempi che ho letto non mostrino il potere dietro procs e lambda.

def zero_function(x)
    x = x.to_s
   if x.length == 1
    return x = "0" + x
   else
    return x
   end
end

zero_lambda = lambda {|x|
  x = x.to_s
   if x.length == 1
    return x = "0" + x
   else
    return x
   end
}

zero_proc = Proc.new {|x|
  x = x.to_s
   if x.length == 1
    puts x = "0" + x
   else
    puts x
   end
}


puts zero_function(4)
puts zero_lambda.call(3)
zero_proc.call(2)

Questa funzione, proc e lambda fanno esattamente la stessa cosa, solo leggermente diversa. C'è qualche ragione per sceglierne uno rispetto all'altro?

    
posta SecurityGate 03.10.2012 - 18:08
fonte

3 risposte

4

Prima di tutto, cosa intendi per "funzioni"? Proc e lambda sono "funzioni" - e valutano un oggetto funzione, che può essere assegnato a una variabile o utilizzato in qualsiasi altra espressione. Non c'è altro modo per definire una "funzione" non di metodo in Ruby.

def , al contrario, definisce un metodo nel modulo corrente (si è sempre all'interno di qualche modulo, in modo esplicito o implicito). Un metodo è ovviamente diverso da una funzione nuda perché un metodo ha implicitamente accesso a self e alle variabili di istanza di self .

Ancora più importante, Proc e lambda sono chiusure: catturano variabili locali dall'ambito di inclusione in cui sono state create, e puoi usare quelle variabili all'interno della chiusura. Ciò consente agli oggetti funzione di mantenere lo stato.

Al contrario, la definizione di un metodo all'interno di un'altra definizione di metodo non consentirà l'accesso alle variabili locali nel corpo del metodo esterno. Quindi è come se avessi spostato all'esterno la definizione interna, eccetto che il metodo definito dal% interno% co_de esisterà solo dopo l'esecuzione del metodo definito dal% esterno% di conteggio.

    
risposta data 04.10.2012 - 20:57
fonte
0

Buona domanda! Sono curioso delle risposte.

Una differenza lo so:

Non ricevi alcun errore con questa chiamata:

zero_proc.call()

Ma ottieni un wrong number of arguments (0 for 1) (ArgumentError) -error con le seguenti chiamate:

puts zero_function()
puts zero_lambda.call()

Metodi e lambda controllano il numero di parametri, non gli oggetti Proc, l'uso nil se mancano i parametri.

    
risposta data 03.10.2012 - 19:43
fonte
0

L'altra grande differenza tra procs, metodi e lambda è il modo in cui affrontano break and return.

Fondamentalmente, un ritorno in un Proc uscirà da qualsiasi metodo di inclusione, e un ritorno da un lambda uscirà solo dal lambda.

Un'interruzione da un Proc tenta di uscire da un'iterazione di inclusione (se non c'è iterazione, riceverai un errore), mentre una pausa da un lambda è come un ritorno.

Maggiori dettagli qui: link

    
risposta data 30.06.2015 - 23:02
fonte

Leggi altre domande sui tag