5 eksempler på den bedste brug af Ruby
Har du nogensinde undret dig over, hvad vi kan gøre med Ruby? Det er nok kun fantasien, der sætter grænser, men vi fortæller gerne om nogle mere eller mindre kendte tilfælde...
Før vi går i gang med at lave en bang-metode, skal vi lære, hvad denne type metode helt præcist er, og hvad der kendetegner den. Lad os starte med det faktum, at der ikke findes nogen entydig definition af denne type metoder. Kort sagt er en bang-metode en metode med et udråbstegn i slutningen.
Vi kan ofte støde på en erklæring om, at bang-metoden på en måde er en farlig metode, og udråbstegnet i slutningen af definitionen fortæller os, at vi skal være på vagt, når vi bruger denne metode. Lad os se: Hvad er denne trussel helt præcist, når det drejer sig om disse metoder, og hvad er deres egenskaber?
En af de mest populære egenskaber ved denne type metoder er, at de normalt ændrer deres publikum. Lad os se på map! metoden som et eksempel. Ifølge dokumentationen påkalder map! metoden den givne blok én gang for hvert element i self og erstatter elementet med den værdi, der returneres af blokken, og hvis der ikke er givet nogen blok, returneres der i stedet en Enumerator.
arry = [1, 2, 3, 4, 5].
arry.object_id => 280
arry.map! {|num| num**num } => [1, 4, 27, 256, 3125]
arry.map! => # [1, 4, 27, 256, 3125]
arry.object_id => 280
Som vi kan se, forbliver object_id uændret. Så faren ved at bruge sådan en metode virker indlysende. Hvis vi i vores Kode vi har brugt variablen arry et andet sted, så vil map! ændre den. Det kan føre til, at vores program fungerer på en uønsket måde eller endda crasher.
Der er objekter i Ruby som ikke kan ændres, f.eks. forekomster af klasserne Integer, Float og Symbol. Mens du arbejder på en projektkan du også møde den såkaldte magiske kommentar, som lyder sådan her:
frozenstrengliteral: true
Hvis man forsøger at ændre String-modtageren i koden, hvor der er brugt en sådan kommentar, vil det resultere i en fejl som denne:
'abc'.upcase!
FrozenError (kan ikke ændre en frossen streng)
Interessant nok var der planer om at indføre en uforanderlig streng i Ruby 3.0men Det blev besluttet ikke at foretage denne ændring.. Man skal dog huske, at ikke alle bang-metoder ændrer modtageren, så man bør altid tjekke i dokumentationen, hvilken slags fare man kan forvente i tilfælde af en bestemt metode.
Et andet karakteristisk træk ved disse metoder er, at mange af dem giver anledning til en undtagelse. Et eksempel på en sådan metode er ActiveRecord::FinderMethods#first! Ifølge dokumentationen er metoden first! den samme som first, men den udløser ActiveRecord::RecordNotFound, hvis der ikke findes nogen post. Bemærk, at first! ikke accepterer nogen argumenter.
Fil activerecord/lib/activerecord/relation/findermethods.rb, linje 128
def første!
first || raiserecordnotfoundexception!
end
Men den ActiveRecord::FinderMethods#first-metode, der bruges ovenfor, ser sådan her ud:
Fil activerecord/lib/activerecord/relation/findermethods.rb, linje 116
def first(limit = nil)
checkreorderdeprecation medmindre loaded?
if limit
findnthwithlimit(0, limit)
else
findnth 0
slut
slut
Takket være ovenstående eksempler ser vi faren ved at bruge førstnævnte. Hvis vi bruger ActiveRecord::FinderMethods#find! og den ikke finder en passende post i databasen, vil den returnere ActiveRecord::RecordNotFound, hvilket kan få vores program til at holde op med at fungere.
Vi skal dog huske, at det ikke betyder, at hvis en metode ikke har et udråbstegn i slutningen, er den sikker og vil ikke udløse undtagelsen eller ændre modtageren.
Et nyt par metoder blev introduceret i Ruby on Rails 6.0: ActiveRecord::Persistence::ClassMethods#insert_all
og ActiveRecord::Persistence::ClassMethods#insert_all!
Den første af disse metoder viser allerede en vis grad af fare. Ifølge dokumentationen skal du indsætteindsætter alle flere poster i databasen i en enkelt SQL INSERT-sætning. Den instansierer ikke nogen modeller og udløser heller ikke ActiveRecord-tilbagekald eller valideringer. Men indsættelsenall! udløser desuden ActiveRecord::RecordNotUnique, hvis nogen rækker overtræder et unikt indeks på tabellen. I så fald bliver der ikke indsat nogen rækker. Det betyder, at den første af disse metoder vil gemme alle poster undtagen dem, der overtræder det unikke indeks, mens den anden (farligere) metode vil udløse en undtagelse og ikke gemme nogen af posterne i databasen.
Mange metoder er farlige at bruge, selv om de ikke har et udråbstegn i slutningen. For eksempel ActiveRecord::FinderMethods#find. Ifølge dokumentationen Hvis der ikke kan findes en eller flere poster for de ønskede id'er, vil ActiveRecord::RecordNotFound blive udløst.
Vi kan se, at selv om denne metode har samme faregrad som ActiveRecord::FinderMethods#first!, har den ikke et udråbstegn.
Det samme gælder, når det drejer sig om at ændre modtageren. For eksempel sletter Array.delete (som dokumenteret) alle elementer fra self, der er lig med object, og returnerer det sidst slettede element eller nil, hvis der ikke findes nogen matchende elementer.
a = [1, 2, 3, 4, 5].
a.object_id #=> 320
a.delete(2) #=> 2
a #=> [1, 3, 4, 5]
a.delete(6) #=> nil
a.object_id #=> 320
Man kan tydeligt se, at objektet er blevet ændret. Det, de to metoder har til fælles, er, at de ikke har et tilsvarende udråbstegn. Hvis den metode, vi ønsker at oprette, har den slags farer, jeg nævnte ovenfor, behøver den derfor ikke umiddelbart at have et udråbstegn i slutningen. Desuden er det tilrådeligt at oprette en bang-metode, hvis der allerede findes en metode med samme navn, som er mindre farlig end den metode, du vil oprette.
Man kan undre sig over, hvorfor man overhovedet bruger disse farlige metoder, især fordi vi normalt har mindre farlige modstykker. En af fordelene kan f.eks. være forbedret kodeydelse takket være en reduktion af antallet af oprettede objekter. Her kan du læse mere om at øge Rails' ydeevne.
Når det drejer sig om at udløse undtagelser, kan det at bruge create-metoden i stedet for den farlige create! føre til en situation, hvor det er svært at opdage en fejl i vores applikation, fordi posterne ikke bliver skrevet ind i databasen. Så hvis vi er sikre på, at de parametre, vi sender til denne metode, er korrekte, bør vi bruge create! metoden, som vil udløse en undtagelse, hvis posten af en eller anden grund ikke bliver gemt i databasen.
Konklusionen er enkel, og den lyder som følger: Fornuftig brug af sådanne metoder kan forbedre ydeevnen og kvaliteten af vores kode. Men vi skal altid huske, at uhensigtsmæssig brug af dem kan forhindre koden i at køre ordentligt.
Hvis du vil lave din egen farlige metode, skal du igennem en bestemt beslutningsproces. Først er spørgsmålet, om der allerede findes en metode med samme navn som den, du vil lave, men som er mindre farlig. Man kan også overveje at lave et par metoder, hvor den ene svarer til den anden, men er farligere.
Der er ingen grund til at lave en bang-metode, hvis dens modstykke uden udråbstegn ikke findes. Der er metoder, som er farlige, fordi de ændrer objektet eller udløser en undtagelse, og alligevel har de ikke et udråbstegn i slutningen af navnet. Hvis du opretter en bang-metode uden et tilsvarende navn, vil det forvirre en programmør, der bruger din kode. Denne person ville ikke være i stand til at sige, hvad faren ved denne metode er, og hvorfor den fortjener et udråbstegn i slutningen af sit navn.
For det andet bør vi overveje, hvilken slags farer vi taler om. Ud fra eksemplerne ovenfor kan vi konkludere, at den mest almindelige type fare er ændringen af selve objektet (i stedet for at oprette en kopi) eller at udløse en undtagelse. Dette er selvfølgelig ikke en regel, men snarere et resultat af at analysere de metoder, der er defineret i Ruby og Ruby on Rails. For eksempel kan vi overveje implementeringen af et metodepar, hvor metoden uden Udråbstegn vil gemme posten i databasen, mens metoden med udråbstegnet vil springe valideringen af denne post over. I dette tilfælde er det tydeligt, hvor den potentielle fare ved at bruge sådanne metoder ligger.
En opsummering af viden om bang-metoder peger på disse konklusioner: Den første metode med udråbstegnet har en mindre truende
modstykke uden udråbstegn, for det andet udfører metoden med udråbstegn en farlig handling, f.eks. ændrer modtageren eller udløser en undtagelse.
Konklusionen er, at forståelsen af begrebet Bang-metoder i Ruby softwareudvikling kan i høj grad forbedre dine kodningsfærdigheder og skabe mere klarhed i din kodebase. Bang-metodersom er markeret med et udråbstegn i slutningen af deres navn, angiver en destruktiv eller potentielt farlig version af en metode. Som konvention er Knald modstykke af en metode skal bruges med forsigtighed, da den kan ændre objekter direkte uden at oprette en separat kopi. Det kan være særligt nyttigt, når man har med foranderlige objekter at gøre, eller når man er interesseret i at optimere ydelsen. Det er dog vigtigt at være forsigtig, når man bruger bang-metoder, da de kan have utilsigtede konsekvenser, hvis de ikke håndteres korrekt. Det er også værd at bemærke, at ikke alle metoder har en Bang-versionog deres tilstedeværelse bør vurderes fra sag til sag. Med viden om, hvornår og hvordan du skal oprette bang-metoder, kan du bruge dette kraftfulde værktøj effektivt og skrive ren, effektiv kode, der opfylder dine specifikke krav.