Ruby for Newbies Iteratorer og blokker

Ruby er et av de mest populære språkene som brukes på nettet. Vi har startet en ny screencast-serie her på Nettuts + som vil introdusere deg til Ruby, samt de flotte rammene og verktøyene som følger med Ruby-utviklingen. I dette kapitlet skal vi snakke om i blokker og iteratorer.


Ta igjen

  • Leksjon 1: Installere Ruby og Komme i gang
  • Leksjon 2: Variabler, datatyper og filer 
  • Leksjon 3: Arbeider med klasser
  • Leksjon 4: Conditionals og Loops
  • Leksjon 5: Iteratorer og blokker

Se Screencast


blokker

I den siste leksjonen snakket vi om løkker. Du vil faktisk ikke bruke sløyfer for ofte i Ruby, på grunn av en funksjon som heter blokker (og-som et resultat av blokker-iteratorer). For å oppdatere minnet ditt, se på de to følgende metallsamtalen (du kan prøve dette i IRB):

navn = "Joe" name.reverse # => "eoJ" name.concat ("rørleggeren") # => "Joe the Plumber"

Som du vet, er parentesene etter metodeanropet vanligvis valgfritt. Vi lærer i dag når de er påkrevd.

Så, her er delene av en metodeanrop:

  • Objektet mottar metoden; Navn ovenfor.
  • Prikken.
  • Metoden navn; omvendt eller concat ovenfor.
  • Argumentene; " rørleggeren" i det andre eksemplet ovenfor.
  • Koden blokk; Følg med!

De første tre delene er nødvendig, selvsagt. Argumentene og kodeblokken er valgfrie. Hva er denne kodeblokken? Se på dette eksemplet, og så diskuterer vi det:

nettsteder = ["net", "psd", "mobile"] sites.map! gjør | side | nettsted + = ".tutsplus.com" sluttsteder # => ["net.tutsplus.com", "psd.tutsplus.com", "mobile.tutsplus.com")

I dette tilfellet er arrayet sider er mottakeren; metoden er kart!. Deretter har vi blokken. Hvis blokken er på flere linjer, kan du bruke søkeordene gjøre og slutt å avgrense det. Hvis du setter det på en enkelt linje, kan du bruke krøllete braces (disse arbeider for multi-line blokker også).

Etter åpningen av blokken har vi blokkparametrene, innenfor rørene ( | ). Hva dette egentlig er, avhenger av metoden du utfører. Den vanligste bruken av blokker er i iteratormetoder, så blokkparameteren vil være det nåværende elementet i looping. Hvis dette høres ganske abstrakt, gjør vi noen få eksempler.


iteratorer

Vi starter med å se på iteratorene av arrays, fordi de er de vanligste sløyfene over ting.

I stedet for å bruke en for loop, vil du sannsynligvis bruke Hver:

nettsteder = ["net", "psd", "mobile"] sites.each | site | setter "# site .tutsplus.com" # net.tutsplus.com # psd.tutsplus.com # mobile.tutsplus.com

Dette er akkurat som å gjøre en for loop; en etter en, hvert element i sider vil bli tildelt til blokkparameteren nettstedet; da vil koden i blokken bli utført.

I tilfelle du er nysgjerrig, Hver Metoden returnerer den opprinnelige gruppen.

Noen ganger vil du returnere en verdi fra blokken. Det er ikke vanskelig å gjøre, hvis du bruker riktig metode.

# antar nettsteder over nettsteder = sites.map do | s | "# s .tutsplus.com" slutten

De kart Metoden samler inn hvilke verdier som returneres fra hver iterasjon av blokken. Deretter returneres en rekke av disse verdiene fra metoden. I dette tilfellet overfører vi sider variabel til den nye gruppen.

Det er en bedre måte å gjøre dette på, skjønt. Flere Ruby-metoder har duplikater med utropstegn (eller bang); Dette betyr at de er ødeleggende: de erstatter verdien de jobber med. Så det ovenfor kunne gjøres på denne måten:

sites.map! | site_prefix | "# site_prefix .tutsplus.com"

Nå, sider vil være en rekke verdier returnert fra blokken.

Mer enn bare arrays har iterator metoder, skjønt. Tall har en ganske kul ganger metode:

5 ganger gjør | i | setter "Loop nummer # i" slutt # Loop nummer 0 # Loop nummer 1 # Loop nummer 2 # Loop nummer 3 # Loop nummer 4

Når du fortsetter koding Ruby, finner du mange nyttige metoder som bruker blokker. Nå, la oss se hvordan du lager våre egne blokker.


Byggeklosser

Nå som du er kjent med bruk av blokker, la oss se hvordan du skriver metoder som utnytter dem. Her er to andre blokker som du ikke har lært enda:

  • Blokkparametere er ikke påkrevd; Du kan skrive en blokk som ikke bruker dem.
  • Blokkene selv kan være valgfrie. Du kan skrive en funksjon som fungerer med eller uten blokker.

Her er hva som skjer, du kaller en metode som tar en blokk. Bak kulissene utfører Ruby noen metodekode, og gir dermed til blokkkode. Etter det blir kontrollen returnert til metoden. La oss sjekke det ut.

Siden de fleste av de enkle iteratorfunksjonene er bygd inn i Ruby, vil vi "omskrive" en av disse. La oss gjøre det Hver metode på arrays:

klasse Array def hver2 i = 0; mens selv [i] gir selv [i] i + = 1 ende selvendets ende

Som du kan se, er dette bare en vanlig metode. Husk at i en instansmetode, selv- søkeord refererer til forekomsten av klassen, i dette tilfellet, Array. Inne i metoden bruker vi en stundsløyfe for å løse over elementene i arrayet. Så, inne i løkken, bruker vi utbytte søkeord. Vi passerer den selv [i]; som vil ende opp med å bli blokkparameteren. Etter det øker vi Jeg for løkken og fortsett.

Hvis vi ønsket at denne metoden skulle returnere mengden verdier som blokken returnerte, kunne vi bare fange den returnerte verdien av utbytte og returnere det, i stedet for selv-, vi returnerer dette matrisen.

klasse Array def hver2_returning_new_values ​​i = 0; new_vals = []; mens selv [i] new_vals [i] = gir selv [i] jeg + = 1 slutten new_vals slutten

Metoder, revidert

La oss avslutte ved å snakke om metoder. Vi vet at ved hjelp av parenteser er valgfritt ... mesteparten av tiden. Her er når du trenger å bruke parentesen når metoden ringer.

Noen ganger har du begge metoden parametere og en blokk.

obj.some_method "param" | x | #block-kode her

Det jeg nettopp har gjort, vil ikke fungere; Vi må bruke parenteser i dette tilfellet, fordi ellers er blokken knyttet til den siste parameteren. Dette er bare tilfellet hvis du bruker de krøllete båndene til å avgrense blokken; hvis du bruker gjøre - slutt, parentesene er ikke nødvendig.

Den andre gangen parentes er nødvendig er når du bestiller en bokstavelig hash (ikke en variabel som peker på en hash) som den første parameteren til metoden. Ruby vil tro det er en blokk, på grunn av den krøllete staven

arr.push : name => "Andrew" # Mislykkes! arr.push (: name => "Andrew") # Passerer