Tancament de robins: blocs, procediments i lambdas: quina diferència hi ha?

Els tancaments a Ruby es poden classificar com a codis que poden passar per objectes i es poden executar posteriorment. Hi ha tres maneres diferents de crear un apagat a Ruby: passar per un mètode de bloc, crear un processador i crear un lambda. Quan creem un tancament a Ruby, el tancament s’uneix al real en el moment de la seva creació (per exemple, variables, mètodes, objectes, etc.). Observo els diversos tancaments de Ruby i parlo de les diferències entre ells.

Blocs

Els blocs es poden identificar mitjançant do..end o {..} i poden ser arguments com es mostra a continuació:

Cada mètode de Ruby pot prendre un bloc opcional com a paràmetre no vàlid, com en l'exemple següent:

A l’exemple anterior, el que això vol dir és que passem al mètode de felicitació i hem d’utilitzar la paraula clau de la collita per iniciar el bloc. Passem una variable local (fent referència a la cadena "Ashley" que va passar el mètode de salut com a argument) per generar el bloc com a argument passat al nom del paràmetre. Inseriu el bloc "Hola # {nom}!" Inscrit. Ara veiem què passa si no ens oposem al bloc.

A l'exemple anterior, no donem l'argument que no es passen arguments al bloc que accepta un paràmetre únic. Estranyament, ArgumentError no es retorna. Això passa perquè els blocs no augmenten el nombre d’arguments. En canvi, quan un bloc accepta un paràmetre, si no passem un argument a un bloc, el paràmetre retorna zero. Com que no es passen arguments al nom del paràmetre de bloc, el nom de la variable local és zero, així que el mètode de salutació és hola. Hi ha un espai addicional on hauria de ser el nom després de la salutació.

Procs

Hi ha dues maneres de crear caixes registradores tal com es mostra a continuació:

En el primer exemple, creem un objecte Proc trucant un nou mètode a la classe Proc i passant-lo al bloc com a argument. En el segon exemple, podem passar pel mòdul del nucli com a argument trucant al mètode proc.

Heu de trucar a l'objecte proc per activar el bloc.

A l'exemple anterior, anomenem mètode de trucada a proc1 que apunta l'objecte proc. Després es passa al mètode de trucada com a argument. estan impreses.

El següent exemple mostra què passa si no anem a una manifestació.

Quan es crida el mètode de trucada a l'objecte Proc1, no ho discutim. Això vol dir que no es passen arguments al nom del paràmetre de bloc. ArgumentError no es va plantejar perquè els projectes compartien les mateixes regles d'aritat que els blocs i no tenien en compte el nombre d'arguments. Com els blocs, si no s’especifica cap paràmetre, s’assigna zero a zero. Hola! és el motiu pel qual obtenim el resultat.

Lambdas

A continuació, hi ha dues maneres de crear lambdas.

En el primer exemple, anomenem el mètode lambda del mòdul Kernel per crear un lambda i passar com a argument com a bloc. En el segon exemple, creem una lambda amb sucre sintàctic de Ruby. En l'exemple que utilitzem -> i després col·loquem el paràmetre de bloc entre claudàtors i després passem al bloc. Per tant, la diferència principal entre les dues maneres diferents de crear un lambda és que en el primer exemple, els paràmetres del bloc es troben dins del bloc, i en el segon exemple, els paràmetres del bloc es troben entre claudàtors en lloc de ->.

Una cosa a destacar és que no podem fer això per crear una lambda:

Això es deu al fet que les lambdas no són objectes Lambda, sinó que són objectes Proc. La principal diferència entre prismes i lambdas és que tenen diferents regles d’arítmia.

Com que les lambdas són objecte de Proc, podem anomenar el mètode de devolució de trucada a lambda i el bloc s’executa. Al primer exemple anterior, anomenem mètode de devolució de trucada a lambda1 i anem al nom del paràmetre de bloc i diem "Hola # {nom}!" Obtenim l’argument Ashley. resultats Hola Ashley !. Al segon exemple, es diu lambda1 sense trucar a l'argument i es retorna ArgumentError ja que el bloc rep un paràmetre. Això demostra que, a diferència dels procediments i els blocs, les lambdas fan que l’argument conte.

Una última cosa ...

Una altra cosa que diferencia els blocs, els cilindres i els xais és com funciona la clau de retorn.

Blocs

Quan utilitzo el codi següent:

He rebut aquest missatge d'error:

retorn inesperat (LocalJumpError)

Així, quan el mètode bloqueja el que passa, l’execució del programa passa des de la implementació del mètode al bloc. Generalment, els programes tornen LocalJumpError quan tenim una implementació de mètode però mai no obtenim cap bloc. Això es tradueix en la implementació del programa des de la implementació del mètode fins a un bloc que no existeix, de manera que es produeix un error. No hi va haver cap obstacle per passar l'error LocalJumpError.

És per aquest motiu que obtenim LocalJumpError a l'exemple anterior. Després que el mètode es passés al bloc, el programa va saltar al bloc que tenia la paraula clau de retorn. LocalJumpError va ser retornat, de manera que va aturar l'execució del programa sense tornar al mètode.

Procs

Quan utilitzo el codi següent:

No faig els mateixos errors que l’exemple de bloc. Una vegada que es crida el Pro i s'avalua la paraula "hola" al bloc, el programa deixa de funcionar i es torna "hola" del mètode proc_exemple. Tingueu en compte que l’última línia del mètode “adéu” no s’ha avaluat mai. Això es deu al fet que els procediments tornen del propi bloc i impedeixen executar el mètode.

Lambdas

Quan utilitzo el codi següent:

La implementació del programa no es va aturar abans del previst. Quan es diu Lambda1 i es diu el bloc, l'execució del programa no es torna del bloc com en la instància del proxy. En canvi, el programa continua funcionant i es retorna "adéu" pel mètode lambda_example. Així, quan s'avalua la paraula clau de retorn en un bloc, lambda ignora la paraula clau de retorn i el programa continua.

Tancar a Rubí pot ser complicat, i si em perdia alguna cosa sobre els tancaments als meus blocs, podeu ser lliure de compartir-los.