A modulok a Crystalben két célt szolgálnak:
Az első cél egy névtér létrehozása, hogy elkerüljük a névütközéseket. Emellett csoportosítja is a kódot, amitől könnyebb megérteni, hogy mire való.
A második cél az, hogy mixineket definiáljunk, amelyekkel a kódot típusok között oszthatjuk meg.
A modulok hasonlítanak az osztályokhoz, de a fő különbség az, hogy nem lehet őket példányosítani, így példányváltozóik sincsenek.
Egy modul deklarálásához a module kulcsszót használod, utána pedig a modul nevét írod.
module Foo
end
A névtér a kód csoportosításának egy módja.
Ezzel elkerülhetők a névütközések, és könnyebb megérteni, hogy mire való a kód.
Ha egy névtérbe helyezett konstanshoz vagy osztályhoz szeretnél hozzáférni, a :: operátort használod.
module Foo
class Bar
end
end
Foo::Bar.new
Ez akkor lehet hasznos, ha például több osztálynak ugyanarra az „alap” funkcionalitásra van szüksége, vagy ha a kódot nem rokon osztályok között kell megosztani. Vagy amikor olyan osztályok között szeretnénk megosztani a kódot, amelyek nem állnak kapcsolatban egymással.
Kétféleképpen használhatsz egy modult mixinként: az első az include kulcsszó használata, a második az extend kulcsszó használata.
Mindkettő elérhetővé teszi a modul konstansait annak a típusnak, amely a modult include-olja vagy extendeli.
Az include a modul összes metódusát példánymetódusként teszi elérhetővé azon a típuson, amelyik a modult include-olja.
Az include kulcsszót a típus elejére kell írni, utána pedig a modul nevét.
module Foo
def foo
"foo"
end
end
class Bar
include Foo
end
Bar.new.foo # => "foo"
Az extend hasonlóan működik az include-hoz, de a metódusokat nem példánymetódusként, hanem osztálymetódusként teszi elérhetővé.
Az extend kulcsszót a típus elejére kell írni, utána pedig a modul nevét.
module Foo
def foo
"foo"
end
end
class Bar
extend Foo
end
Bar.foo # => "foo"
A Crystalben gyakori minta az, hogy egy modulban az extend self mintát használjuk.
Ezzel a modul összes metódusa osztálymetódusként lesz elérhető magán a modulon.
Ez azt jelenti, hogy nem kell minden metódust a def self.method_name szintaxissal a modulhoz rendelned.
module Foo
extend self
def foo
"foo"
end
end
Foo.foo # => "foo"
A Bellebrook Basketball League egy liga, amelyben több csapat szerepel, és mindegyiknek megvan a maga játékoskerete. Mindjárt kezdődik egy új szezon, és szükségük van egy új jegyértékesítő rendszerre, amellyel jegyeket adhatnak el a mérkőzésekre. A múlt szezonban a stadion bejáratánál árulták a jegyeket, de a népszerűség az egekbe szökött, ezért úgy döntöttek, hogy ebben a szezonban online értékesítik a jegyeket, hogy lépést tartsanak a megnövekedett kereslettel.
A liga felvette veled a kapcsolatot, és megkért, hogy készíts egy rendszert a jegyeladások kezelésére.
Először is létre kell hoznod egy jegyértékesítő rendszert, amely a jegyeladásokat kezeli. A jegyértékesítő rendszernek meg kell tudnia mondani, hány jegy érhető el egy mérkőzésre.
Minden mérkőzéshez létre kell hozni a TicketSystem nevű osztály egy példányát.
A kezdőértéknek a következő adatokat kell tartalmaznia:
A kezdőértéket olyan argumentumokból hozd létre, amelyek megadják az elérhető jegyek számát, illetve azt, hogy melyik stadionban játsszák a mérkőzést.
A kezdőérték a @tickets_available és a @stadium példányváltozóból álljon.
Ezekben rendre az első, illetve a második argumentum szerepeljen.
TicketSystem.new(100, "Bellebrook")
# => #<TicketSystem:0x10f0b8 @tickets_available=100, @stadium="Bellebrook">
Először is létre kell hoznod egy metódust, amely visszaadja az adott mérkőzésre elérhető jegyek számát.
Definiálj egy TicketingReservation nevű modult a már definiált osztály fölé.
Ezt a modult be kell foglalni a TicketSystem osztályba.
A modulon belül definiálj egy tickets_available nevű metódust.
Ez a metódus adja vissza az elérhető jegyek számát.
ticket_system = TicketSystem.new(100)
ticket_system.tickets_available
#=> 100
Létre kell hoznod egy metódust, amely ellenőrzi, hogy van-e elérhető jegy egy adott mérkőzésre. A mérkőzésre 100 jegyet kell tartalékban tartani. Ez biztosítja, hogy mindig legyen jegy azoknak, akik a stadion bejáratánál vásárolnak.
A TicketingReservation modulon belül definiálj egy order_ticket? nevű metódust.
A metódus true-t adjon vissza, ha legalább 100 jegy elérhető, egyébként pedig false-t.
Ha legalább 100 jegy elérhető, a metódus csökkentse is eggyel az elérhető jegyek számát.
ticket_system = TicketSystem.new(100)
ticket_system.order_ticket?
#=> true
A jegyértékesítő rendszer üzeneteinek könnyen érthetőnek kell lenniük a felhasználók számára. Az üzenetek legyenek személyesek is, ezért tartalmazzák a felhasználó nevét.
Ha a jegyvásárlás sikeres volt, a felhasználó kapjon egy üzenetet, amely megmondja, hogy a vásárlás sikeres volt, megadja a jegye számát, és azt is, hogy melyik stadionban játsszák a mérkőzést. A jegy számának a rendelés előtt elérhető jegyek számának kell lennie.
Ha a vásárlás sikeres volt, az üzenet így nézzen ki: {name}, your purchase was successful, your ticket number is #{ticket_number}, and the game is played at the {stadium_name} stadium..
Ha a vásárlás sikertelen volt, az üzenet így nézzen ki: {name}, your purchase was unsuccessful, there are not enough tickets available..
A TicketingReservation, modulon belül definiálj egy order_message nevű metódust, amely egy name argumentumot kap, ami a vásárló nevét tartalmazza.
A metódus egy stringet adjon vissza az üzenettel.
ticket_system = TicketSystem.new(100, "Bellebrook")
ticket_system.order_message("John")
#=> "John, your purchase was successful, your ticket number is #100, and the game is played at the Bellebrook stadium."
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Crystal nyelvet 26 fogalom142 feladat segítségével, valódi emberi mentorálással, mindez ingyen.