Track
/
Crystal
Crystal
/
Esercizi
/
Lo spremifrutta di Johannes
Lo spremifrutta di Johannes

Lo spremifrutta di Johannes

Esercizio di apprendimento

Introduzione

Le classi sono un concetto centrale nella programmazione orientata agli oggetti. In Crystal, tutto è un oggetto, ogni oggetto ha un tipo e può rispondere ad alcuni metodi. Le classi sono modelli per creare oggetti: forniscono valori iniziali per lo stato, come le variabili, e implementazioni di comportamento, come i metodi. Gli oggetti sono istanze di classe che contengono tutte le variabili di istanza e gli stati.

Definizione di una classe

Una classe si definisce con la parola chiave class, seguita dal nome della classe scritto in UpperCamelCase.

class Account
end

Creare un'istanza

Per creare un'istanza di una classe, chiama il nome della classe usando il metodo new.

class Account
end

account = Account.new

Nell'esempio qui sopra, la variabile account è un'istanza della classe Account.

Quando si crea un'istanza, un metodo speciale chiamato initialize funge da costruttore. Viene chiamato quando si crea un'istanza. Il costruttore permette di impostare lo stato iniziale dell'istanza. Il metodo initialize può accettare argomenti, che vengono passati quando si crea un'istanza.

class Account
  def initialize(number)
    5 + number # => 9
  end
end

Account.new(4)
Note

Il metodo initialize non può restituire manualmente un valore: al suo posto, new restituisce l'istanza appena creata.

class Account
  def initialize(number)
    5 + number
  end
end

Account.new(4)
# => #<Account:0x7f5dc33dcea0>

Metodi di istanza

Un metodo di istanza è un metodo disponibile per un'istanza di una classe, e può essere chiamato su quell'istanza. I metodi di istanza si definiscono con la parola chiave def, seguita dal nome del metodo. Si definiscono all'interno della definizione della classe.

class Account
  def balance
    100
  end
end

account = Account.new
account.balance # => 100

Variabili di istanza

Le variabili di istanza sono variabili disponibili in tutti i metodi dell'istanza. Per accedere a una variabile di istanza devi definire un metodo di istanza. Possono essere inizializzate nel metodo initialize. Si definiscono usando il prefisso @.

class Account
  def initialize
    @balance = 100
  end

  def balance
    @balance
  end
end

account = Account.new
account.balance
# => 100

Le variabili di istanza possono anche essere definite all'interno della definizione della classe.

class Account
  @age = 0
end

Variabili di istanza con inizializzazione

Le variabili di istanza possono essere inizializzate con un argomento passato al metodo initialize. Poiché Crystal non riesce a inferire il tipo dell'argomento usato durante l'inizializzazione, questo va specificato. Se vuoi saperne di più, puoi leggere: type-inference. Per specificare il tipo della variabile puoi usare il simbolo :, seguito dal tipo. Per esempio, se vuoi creare una variabile di istanza chiamata balance di tipo Int32, puoi fare così: @balance : Int32. Oppure, se vuoi creare una variabile di istanza chiamata raining di tipo Bool, puoi fare così: @raining : Bool.

Ci sono diversi modi per farlo. Uno è dichiarare l'argomento con il tipo nel metodo initialize e poi assegnare la variabile di istanza all'argomento, come nell'esempio seguente:

class Account
  def initialize(balance : Int32)
    @balance = balance
  end

  def balance
    @balance
  end
end

account = Account.new(1)
account_2 = Account.new(5)

account.balance
# => 1

account_2.balance
# => 5

Un altro modo è dichiarare il tipo della variabile di istanza nella definizione della classe nella forma: @<variable> : <Type>, come nell'esempio seguente:

class Weather

  @raining : Bool

  def initialize(raining)
    @raining = raining
  end

  def raining
    @raining
  end
end

weather = Weather.new(true)
weather.raining
# => true

Modificare le variabili di istanza

I metodi possono modificare le variabili di istanza. Questi metodi possono essere chiamati sull'istanza della classe. Quando un metodo modifica una variabile di istanza, quella modifica è disponibile solo nell'istanza della classe su cui l'hai chiamato.

class Account
  def initialize(balance : Int32)
    @balance = balance
  end

  def withdraw(amount)
    @balance -= amount
  end

  def balance
    @balance
  end
end

account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10

account_2.balance
# => 10

account.withdraw(5)
account.balance
# => 5

account_2.balance
# => 10

Metodi di classe

I metodi di classe sono metodi definiti per una classe, ma non per le sue istanze. Offrono un modo per creare metodi che non dipendono dallo stato dell'istanza. Si definiscono con la parola chiave def, seguita da self.<method name>. self è un riferimento al namespace da cui viene chiamato self. In questo caso, si riferisce alla classe Account. Sarebbe lo stesso che scrivere Account., ma self. è il modo preferito.

class Account
  def self.balance
    100
  end
end

Account.balance
# => 100

Istruzioni

Il tuo amico Johannes adora costruire hardware fai da te (DIY). Ha appena costruito una macchina per il succo e Johannes ne è entusiasta. L'obiettivo di Johannes è riuscire a preparare un succo fresco ogni mattina.

La macchina per il succo di Johannes ha tante funzionalità sofisticate. Per esempio un sistema di misurazione integrato, che ti dice quanto succo c'è nella tazza. Ha anche un timer, che ti dice da quanto tempo la macchina è in funzione.

Johannes non è un grande programmatore, ma vuole scrivere un programma per controllare la macchina. Per questo ti ha chiesto aiuto.

1. Luce di debug

La macchina ha una luce di debug, un meccanismo semplice: se la macchina è alimentata, la luce di debug è accesa. Il programma funziona solo se la luce di debug è accesa.

Questo metodo dovrebbe essere un metodo di classe chiamato JuiceMaker.

Definisci il metodo di classe JuiceMaker.debug_light_on? che restituisce true.

JuiceMaker.debug_light_on?
#=> true

2. Inizializzare la macchina

Quando la macchina viene accesa, dovrebbe creare un'istanza di una classe chiamata JuiceMaker. La macchina dovrebbe avere uno stato inizializzato, cioè le informazioni che descrivono la situazione attuale della macchina. Lo stato inizializzato dovrebbe contenere le seguenti informazioni:

  1. Se la macchina è in funzione o no. Questo dovrebbe essere sempre false quando la macchina viene accesa.
  2. La quantità di succo nella tazza: sarà un sensore che misurerà la quantità di succo nella tazza.

Definisci lo stato inizializzato, che prende come parametro la quantità di succo nella tazza, e costruisci lo stato inizializzato. Lo stato inizializzato dovrebbe ospitare una variabile di istanza @running impostata a false, e una variabile di istanza @fluid basata su un argomento passato quando la classe viene inizializzata.

JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>

3. Accendere la macchina

La macchina può essere accesa e spenta. Devi definire un metodo per accendere la macchina. Quando la macchina viene accesa, lo stato di funzionamento dovrebbe essere impostato a true.

Definisci il metodo JuiceMaker#start, che accende la macchina.

juice_maker = JuiceMaker.new(5)
juice_maker.start

juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>

4. Stato della macchina

La macchina deve poter indicare il proprio stato. Dovrebbe restituire true se la macchina è in funzione, e false se non lo è.

Definisci il metodo JuiceMaker#running?, che restituisce lo stato della macchina.

juice_maker = JuiceMaker.new(5)
juice_maker.start

juice_maker.running?
#=> true

5. Aggiungere il succo

La macchina può aggiungere succo alla tazza. La macchina sa quanto succo viene aggiunto alla tazza. La macchina ha bisogno di aiuto per sapere quanto succo c'è nella tazza dopo che è stato aggiunto.

Definisci il metodo JuiceMaker#add_fluid, che prende come parametro la quantità di succo aggiunta e aggiorna la quantità di succo nella tazza.

juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)

juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>

6. Spegnere la macchina

La macchina può essere accesa e spenta. Devi definire un metodo per spegnere la macchina. Questo metodo viene chiamato solo quando la macchina è in funzione. Quando la macchina viene spenta, lo stato di funzionamento dovrebbe essere impostato a false. La macchina ha anche bisogno di aiuto per determinare quanto succo c'è nella tazza dopo che è stata spenta. La macchina consuma cinque unità di succo al minuto.

Definisci il metodo JuiceMaker#stop, che prende come parametro il numero di minuti in cui la macchina è rimasta in funzione e restituisce la quantità di succo nella tazza dopo che la macchina è stata spenta.

juice_maker = JuiceMaker.new(5)

juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>

juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Crystal Exercism

Vuoi iniziare Lo spremifrutta di Johannes?

Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.