5 exempel på hur Ruby används på bästa sätt
Har du någonsin undrat vad vi kan göra med Ruby? Tja, himlen är förmodligen gränsen, men vi är glada att prata om några mer eller mindre kända fall ...
Innan vi börjar skapa en bang-metod, låt oss lära oss vad exakt den här typen av metod är och vilka egenskaper den har. Låt oss börja med det faktum att det inte finns någon entydig definition av dessa typer av metoder. Enkelt uttryckt är en bang-metod en metod med ett utropstecken i slutet.
Vi kan ofta stöta på ett uttalande om att bang-metoden på sätt och vis är en farlig metod och utropstecknet i slutet av dess definition säger oss att vi ska vara vaksamma när vi använder denna metod. Låt oss se: vad är detta hot exakt när det gäller dessa metoder och vad är deras egenskaper?
En av de mest populära egenskaperna hos dessa typer av metoder är att de vanligtvis ändrar sin publik. Låt oss ta en titt på map! -metoden som ett exempel. Enligt dokumentationen anropar map! -metoden det givna blocket en gång för varje element i self, ersätter elementet med det värde som returneras av blocket och om inget block ges returneras en Enumerator istället.
arry = [1, 2, 3, 4, 5]
arry.object_id => 280
arry.map! {|num| num**num } => [1, 4, 27, 256, 3125]
arry.karta! => #
arry.map! {|n| n } => [1, 4, 27, 256, 3125]
arry.object_id => 280
Som vi kan se förblir object_id oförändrat. Så faran med att använda en sådan metod verkar uppenbar. Om vi i vårt kod vi använt variabeln arry någon annanstans, så kommer map! att ändra den. Detta kan leda till att vårt program fungerar på ett oönskat sätt eller till och med kraschar.
Det finns objekt i Ruby som inte kan ändras, t.ex. instanser av klasserna Integer, Float och Symbol. Under arbetet med en projektkan du också möta den så kallade magiska kommentaren som går så här:
frozensträngliteral: true
Om man försöker ändra String-mottagaren i koden där en sådan kommentar användes skulle det resultera i ett fel som detta:
'abc'.upcase!
FrozenError (kan inte modifiera frusen sträng)
Intressant nog fanns det planer på att införa oföränderlig String i Ruby 3.0, men beslutades det att inte göra denna ändring. Man bör dock komma ihåg att inte alla bang-metoder ändrar mottagaren, så du bör alltid kontrollera i dokumentationen vilken typ av fara du kan förvänta dig i fallet med en viss metod.
Ett annat utmärkande drag för dessa metoder är att det för många av dem uppstår ett undantag. Ett exempel på en sådan metod är ActiveRecord::FinderMethods#first! Enligt dokumentationen är metoden first! samma som first men ger ActiveRecord::RecordNotFound om ingen post hittas. Observera att first! inte accepterar några argument.
Fil activerecord/lib/activerecord/relation/findermethods.rb, rad 128
def första!
first || raiserecordnotfoundexception!
slut
Men ActiveRecord::FinderMethods#first-metoden som används ovan ser ut så här:
Fil activerecord/lib/activerecord/relation/findermethods.rb, rad 116
def first(limit = nil)
checkreorderdeprecation om inte laddad?
if gräns
hitta med gräns(0, gräns)
annars
findnth 0
slut
slut
Tack så ovanstående exempel, vi ser faran med att använda den förra. Om vi använder ActiveRecord::FinderMethods#find! och det inte hittar en lämplig post i databasen, kommer det att returnera ActiveRecord::RecordNotFound, vilket kan leda till att vårt program slutar fungera.
Vi måste dock komma ihåg att detta inte betyder att om en metod inte har ett utropstecken i slutet är den säker och kommer inte att ge upphov till undantaget eller ändra mottagaren.
Ett nytt par metoder introducerades i Ruby on Rails 6.0: ActiveRecord::Persistens::KlassMetoder#insert_all
och ActiveRecord::Persistence::ClassMethods#insert_all!
Den första av dessa metoder visar redan en viss grad av fara. Tja, enligt dokumentationen, infogaalla infogar flera poster i databasen i en enda SQL INSERT-sats. Den instansierar inte några modeller och utlöser inte heller ActiveRecord callbacks eller valideringar. Men insättningenall! ger dessutom ActiveRecord::RecordNotUnique om några rader bryter mot ett unikt index på tabellen. I så fall infogas inga rader. Detta innebär att den första av dessa metoder kommer att spara alla poster utom de som bryter mot det unika indexet, medan den andra (farligare) metoden kommer att ge upphov till ett undantag och inte spara någon av posterna i databasen.
Många metoder, även om de inte har ett utropstecken i slutet, är farliga att använda. Till exempel ActiveRecord::FinderMethods#find. Enligt dokumentationen Om en eller flera poster inte kan hittas för de begärda ID: erna, kommer ActiveRecord::RecordNotFound att höjas.
Vi kan se att även om den här metoden har samma farlighetsgrad som ActiveRecord::FinderMethods#first! så har den inget utropstecken.
Detsamma gäller när det gäller att modifiera mottagaren. Till exempel tar Array.delete (som dokumenterat) bort alla objekt från self som är lika med object och returnerar det senast borttagna objektet, eller nil om inga matchande objekt hittas.
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
Du kan tydligt se att objektet har modifierats. Det de två metoderna har gemensamt är att de inte har någon motsvarighet i form av ett utropstecken. Om den metod vi vill skapa skulle ha den typ av faror som jag nämnde ovan, behöver den därför inte omedelbart ha ett utropstecken i slutet. Dessutom är det lämpligt att skapa en bang-metod om det redan finns en metod med samma namn som är mindre farlig än den metod du vill skapa.
Man kan undra varför man överhuvudtaget använder dessa farliga metoder, särskilt som vi oftast har mindre farliga motsvarigheter. En av fördelarna kan t.ex. vara förbättrad kodprestanda tack vare att antalet skapade objekt minskar. Här kan du läsa mer om hur du ökar prestandan i Rails.
När det gäller att skapa undantag kan användning av create-metoden istället för den farliga create! leda till en situation där ett fel i vår applikation är svårt att upptäcka eftersom posterna inte kommer att skrivas in i databasen. Så om vi är säkra på att parametrarna vi skickar till den här metoden är korrekta, bör vi använda metoden create! som kommer att ge upphov till ett undantag om posten av någon anledning inte sparas i databasen.
Slutsatsen är enkel och lyder som följer: Försiktig användning av sådana metoder kan förbättra prestandan och kvaliteten på vår kod. Vi måste dock alltid komma ihåg att olämplig användning av dem kan hindra koden från att fungera korrekt.
Om man vill bygga en egen farlig metod måste man gå igenom en viss beslutsprocess. Först är frågan om det redan finns en metod med samma namn som den du vill skapa men som är mindre farlig. Du kan också överväga att skapa ett par metoder där den ena är likvärdig med den andra, men farligare.
Det är ingen mening med att skapa en bang-metod om dess motsvarighet utan utropstecken inte finns. Det finns metoder som är farliga eftersom de ändrar objektet eller ger upphov till ett undantag, och ändå har de inte ett utropstecken i slutet av namnet. Att skapa en bang-metod utan motsvarighet skulle förvirra en programmerare som använder din kod. Den personen skulle inte kunna säga vad som är farligt med den här metoden och varför den förtjänar ett utropstecken i slutet av sitt namn.
För det andra bör vi överväga vilken typ av faror vi talar om. Från exemplen ovan kan vi dra slutsatsen att den vanligaste typen av fara är förändringen av själva objektet (istället för att skapa dess kopia) eller höja ett undantag. Naturligtvis är detta inte en regel utan snarare ett resultat av att analysera de metoder som har definierats i Ruby och Ruby on Rails. Vi kan till exempel överväga implementeringen av ett metodpar där metoden utan utropstecken skulle spara posten i databasen, medan metoden med utropstecknet skulle hoppa över valideringen av denna post. I det här fallet är det tydligt var den potentiella faran med att använda sådana metoder ligger.
En sammanfattning av kunskapen om bang-metoder pekar på dessa slutsatser: den 1:a metoden med utropstecknet har en mindre hotfull
utan utropstecken, för det andra utför metoden med utropstecken en farlig åtgärd, t.ex. ändrar mottagaren eller utlöser ett undantag.
Sammanfattningsvis kan förståelsen av begreppet bang-metoder i Ruby Utveckling av programvara kan avsevärt förbättra dina kodningskunskaper och göra din kodbas tydligare. Bang-metodersom betecknas med ett utropstecken i slutet av deras namn, anger en destruktiv eller potentiellt farlig version av en metod. Enligt konvention är bang motpart av en metod bör användas med försiktighet eftersom den kan modifiera objekt direkt, utan att skapa en separat kopia. Detta kan vara särskilt användbart när man har att göra med föränderliga objekt eller när prestandaoptimering är ett problem. Det är dock viktigt att vara försiktig när man använder bang-metoder, eftersom de kan få oavsiktliga konsekvenser om de inte hanteras på rätt sätt. Det är också värt att notera att inte alla metoder har en bang-versionoch deras närvaro bör utvärderas från fall till fall. Med kunskap om när och hur man skapar bang-metoder kan du använda detta kraftfulla verktyg på ett effektivt sätt och skriva ren och effektiv kod som uppfyller dina specifika krav.