Ruby Closure: Bloky, procedury a lambdy - jaký je rozdíl?

Uzávěry v Ruby lze klasifikovat jako kód, který může procházet objekty a může být proveden později. Existují tři různé způsoby, jak v Ruby vytvořit vypnutí - projít blokovou metodou, vytvořit procesor a vytvořit lambdu. Když v Ruby vytvoříme uzávěr, uzávěr se váže na skutečný v době jeho vytvoření (například proměnné, metody, objekty atd.). Podívám se na různé uzávěry v Ruby a diskutuji o rozdílech mezi nimi.

Bloky

Bloky lze identifikovat pomocí příkazu do..end nebo {..} a mohou to být argumenty, jak je uvedeno níže:

Každá metoda v Ruby může vzít volitelný blok jako neplatný parametr, jako v následujícím příkladu:

Ve výše uvedeném příkladu to znamená, že přecházíme na metodu pozdravu a ke spuštění bloku musíme použít klíčové slovo sklizně. Předáme lokální proměnnou (s odkazem na řetězec „Ashley“, který prošel jako uvítací metodu pozdrav), abychom generovali blok jako argument předaný názvu parametru. Uvnitř bloku: „Ahoj # {name}!“ Napsáno. Nyní se podívejme, co se stane, pokud nebudeme proti bloku protestovat.

Ve výše uvedeném příkladu neposkytujeme argument, že do bloku, který přijímá jediný parametr, nejsou předávány žádné argumenty. Kupodivu se ArgumentError nevrací. Důvodem je, že bloky nezvyšují počet argumentů. Místo toho, když blok přijme parametr, pokud do bloku nepředáme argument, vrátí parametr nulu. Protože do názvu parametru bloku nejsou předány žádné argumenty, název místní proměnné je nula, takže metoda pozdravu je ahoj! tam je další prostor, kde by měl být název po pozdravu.

Procs

Existují dva způsoby, jak vytvořit registrační pokladny, jak je uvedeno níže:

V prvním příkladu vytvoříme objekt Proc voláním nové metody ve třídě Proc a jejím předáním v bloku jako argumentu. Ve druhém příkladu můžeme modulem jádra projít jako argument voláním metody proc.

Chcete-li blok aktivovat, musíte zavolat proc objekt.

Ve výše uvedeném příkladu voláme metodu volání v proc1, která ukazuje na objekt proc. Poté je předán do metody volání jako argument. jsou vytištěny.

Následující příklad ukazuje, co se stane, pokud nebudeme chodit na rally.

Když se volá metoda volání v objektu Proc proc1, nehádáme se. To znamená, že do parametru bloku nejsou předány žádné argumenty. ArgumentError nebyl vznesen, protože projekty sdílely stejná pravidla pro arity jako bloky a nezohlednily počet argumentů. Stejně jako u bloků, není-li zadán žádný parametr, nula je přiřazena nule. Ahoj! je důvod, proč jsme dostali výsledek.

Lambdas

Zde jsou dva způsoby, jak vytvořit lambda.

V prvním příkladu voláme metodu lambda z modulu jádra, abychom vytvořili lambda a předali jako argument jako blok. Ve druhém příkladu vytváříme lambdu pomocí Rubyho syntaktického cukru. V příkladu použijeme -> a pak umístíme parametr bloku do hranatých závorek a poté se přesuneme do bloku. Hlavní rozdíl mezi dvěma různými způsoby, jak vytvořit lambda, spočívá v tom, že v prvním příkladu jsou parametry bloku uvnitř bloku a ve druhém příkladu jsou parametry bloku v závorkách místo ->.

Jedna věc k poznámce je, že to nemůžeme udělat, abychom vytvořili lambdu:

Je to proto, že lambdy ve skutečnosti nejsou Lambda objekty, jsou to Proc objekty. Hlavní rozdíl mezi hranoly a jehňaty je v tom, že mají různá pravidla arytmie.

Protože lambdy jsou předmětem Proc, můžeme v lambda zavolat metodu zpětného volání a blok se provede. V prvním příkladu výše nazýváme metodu zpětného volání v lambda1 a jdeme na název parametru bloku a řekneme „Hello # {name}!“ Pojďme získat Ashleyho argument. výsledky Ahoj Ashley! Ve druhém příkladu je lambda1 volána bez vyvolání argumentu a ArgumentError je vrácena, když blok obdrží jeden parametr. To ukazuje, že na rozdíl od procedur a bloků, lambda počítá argumenty.

Jedna poslední věc ...

Další věcí, která odděluje bloky, válce a jehňata, je to, jak funguje klávesa pro návrat.

Bloky

Když použiju následující kód:

Obdržel jsem tuto chybovou zprávu:

návrat neočekávaný (LocalJumpError)

Když tedy metoda blokuje to, co se děje, provádění programu přejde z implementace metody do bloku. Obecně platí, že programy vrátí LocalJumpError, když máme implementaci metody, ale nikdy nedostaneme blok. Výsledkem je implementace programu z implementace metody do bloku, který neexistuje, takže dojde k chybě. Neexistovala žádná překážka při předávání chyby LocalJumpError!

To je přesně důvod, proč jsme v příkladu výše dostali LocalJumpError. Poté, co metoda předala bloku, program skočil do bloku, který měl návratové klíčové slovo. LocalJumpError byl vrácen, takže zastavil provádění programu bez návratu k metodě.

Procs

Když použiju následující kód:

Nedělám stejné chyby jako příklad bloku. Jakmile je Pro vyvolán a v bloku je vyhodnoceno slovo „ahoj“, program se zastaví a „ahoj“ je vrácena z metody proc_example. Všimněte si, že poslední řádek „dobré“ metody nebyl nikdy vyhodnocen. Důvodem je, že procedura se vrací ze samotného bloku a zastavuje provádění metody.

Lambdas

Když použiju následující kód:

Provádění programu se nezastavilo předem. Když se volá Lambda1 a vyvolá se blok, provedení programu se nevrátí z bloku jako v instanci proxy. Místo toho program pokračuje v běhu a „sbohem“ se vrací metoda lambda_example. Při hodnocení návratového klíčového slova v bloku tedy lambda ignoruje návratové klíčové slovo a program pokračuje.

Zavírání na Ruby může být složité a pokud jste na mém uzavření blogů něco zmeškali, můžete je zdarma sdílet!