Rutas
/
Crystal
Crystal
/
Ejercicios
/
El exprimidor de Johannes
El exprimidor de Johannes

El exprimidor de Johannes

Ejercicio de aprendizaje

Introducción

Las clases son un concepto central en la programación orientada a objetos. En Crystal, todo es un objeto, cada objeto tiene un tipo y puede responder a algunos métodos. Las clases son planos para crear objetos: proporcionan valores iniciales para el estado, como las variables, e implementaciones del comportamiento, como los métodos. Los objetos son instancias de clase que contienen todas las variables de instancia y los estados.

Definición de clase

Una clase se define con la palabra clave class, seguida del nombre de la clase escrito en UpperCamelCase.

class Account
end

Crear una instancia

Para crear una instancia de una clase, llama al nombre de la clase con el método new.

class Account
end

account = Account.new

En el ejemplo anterior, la variable account es una instancia de la clase Account.

Al crear una instancia, un método especial llamado initialize actúa como constructor. Se llama cuando se crea una instancia. El constructor te permite establecer el estado inicial de la instancia. El método initialize puede recibir argumentos, que se pasan al crear una instancia.

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

Account.new(4)
Note

El método initialize no puede devolver un valor manualmente; en su lugar, new devuelve la instancia recién creada.

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

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

Métodos de instancia

Un método de instancia es un método disponible para una instancia de una clase y se puede llamar sobre esa instancia. Los métodos de instancia se definen con la palabra clave def, seguida del nombre del método. Se definen dentro de la definición de la clase.

class Account
  def balance
    100
  end
end

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

Variables de instancia

Las variables de instancia son variables disponibles en todos los métodos de la instancia. Para acceder a una variable de instancia, necesitas definir un método de instancia. Se pueden inicializar en el método initialize. Se definen con el prefijo @.

class Account
  def initialize
    @balance = 100
  end

  def balance
    @balance
  end
end

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

Las variables de instancia también se pueden definir dentro de la definición de la clase.

class Account
  @age = 0
end

Variables de instancia con inicialización

Las variables de instancia se pueden inicializar con un argumento que se pasa al método initialize. Como Crystal no puede inferir el tipo del argumento usado durante la inicialización, hay que especificarlo. Si quieres leer más sobre esto, puedes consultar: inferencia de tipos. Para especificar el tipo de la variable, puedes usar el símbolo :, seguido del tipo. Por ejemplo, si quieres crear una variable de instancia llamada balance de tipo Int32, puedes hacer lo siguiente: @balance : Int32. O si quieres crear una variable de instancia llamada raining de tipo Bool, puedes hacer lo siguiente: @raining : Bool.

Hay varias formas de implementar esto: por ejemplo, declarar el argumento con su tipo en el método initialize y luego asignar la variable de instancia al argumento, como en el ejemplo siguiente:

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

Otra forma es declarar el tipo de la variable de instancia en la definición de la clase con la forma @<variable> : <Type>, como en el ejemplo siguiente:

class Weather

  @raining : Bool

  def initialize(raining)
    @raining = raining
  end

  def raining
    @raining
  end
end

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

Modificar variables de instancia

Los métodos pueden modificar variables de instancia. Estos métodos se pueden llamar sobre la instancia de la clase. Cuando un método modifica una variable de instancia, ese cambio solo está disponible en la instancia de la clase sobre la que lo llamaste.

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

Métodos de clase

Los métodos de clase son métodos que se definen para una clase, pero no para sus instancias. Ofrecen una forma de crear métodos que no dependen del estado de la instancia. Se definen con la palabra clave def, seguida de self.<method name>. self es una referencia al espacio de nombres desde el que se llama a self. En este caso, se refiere a la clase Account. Sería lo mismo que escribir Account., pero self. es la forma preferida.

class Account
  def self.balance
    100
  end
end

Account.balance
# => 100

Instrucciones

A tu amigo Johannes le encanta el hardware de bricolaje (hazlo tú mismo). Acaba de construir una máquina de zumo y le hace mucha ilusión. El objetivo de Johannes es poder preparar zumo fresco todas las mañanas.

La máquina de zumo de Johannes tiene un montón de funcionalidades sofisticadas. Por ejemplo, un sistema de medición integrado que puede decirte cuánto zumo hay en el vaso. También tiene un temporizador que te dice cuánto tiempo lleva funcionando la máquina.

Johannes no es el mejor programando, pero quiere hacer un programa para controlar la máquina. Por eso te ha pedido que le ayudes.

1. Luz de debug

La máquina tiene una luz de debug, es un mecanismo sencillo: si la máquina recibe corriente, la luz de debug está encendida. El programa solo se ejecutará si la luz de debug está encendida.

Este método debe ser un método de clase llamado JuiceMaker.

Define el método de clase JuiceMaker.debug_light_on? que devuelve true.

JuiceMaker.debug_light_on?
#=> true

2. Inicializar la máquina

Cuando se enciende la máquina, debe crear una instancia de una clase llamada JuiceMaker. Se supone que la máquina tiene un estado inicializado. El estado inicializado debe contener la siguiente información:

  1. Si la máquina está funcionando o no. Esto debe ser siempre false cuando se enciende la máquina.
  2. La cantidad de zumo que hay en el vaso; este será un sensor que medirá la cantidad de zumo en el vaso.

Define el estado inicializado, que toma la cantidad de zumo en el vaso como parámetro, y construye el estado inicializado. El estado inicializado debe albergar una variable de instancia @running que se establece en false, y una variable de instancia @fluid que se basa en un argumento dado cuando se inicializa la clase.

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

3. Encender la máquina

La máquina se puede encender y apagar. Tienes que definir un método para encender la máquina. Cuando se enciende la máquina, el estado de funcionamiento debe establecerse en true.

Define el método JuiceMaker#start, que enciende la máquina.

juice_maker = JuiceMaker.new(5)
juice_maker.start

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

4. Estado de la máquina

La máquina tiene que poder decirte cuál es su estado. Debe devolver true si la máquina está funcionando y false si no lo está.

Define el método JuiceMaker#running? que devuelve el estado de la máquina.

juice_maker = JuiceMaker.new(5)
juice_maker.start

juice_maker.running?
#=> true

5. Añadir zumo

La máquina puede añadir zumo al vaso. La máquina puede saber cuánto zumo se añade al vaso. La máquina necesita ayuda para saber cuánto zumo hay en el vaso después de añadirlo.

Define el método JuiceMaker#add_fluid, que toma la cantidad de zumo añadida como parámetro y actualiza la cantidad de zumo en el vaso.

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

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

6. Apagar la máquina

La máquina se puede encender y apagar. Tienes que definir un método para apagar la máquina Este método solo se llamará cuando la máquina esté funcionando. Cuando se apague la máquina, el estado de funcionamiento debe establecerse en false. La máquina también necesita ayuda para determinar cuánto zumo hay en el vaso después de apagarse. La máquina consume cinco unidades de zumo por minuto.

Define el método JuiceMaker#stop, que toma el número de minutos que la máquina ha estado funcionando como parámetro y devuelve la cantidad de zumo en el vaso después de apagar la máquina.

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>
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Crystal Exercism

¿Listo para empezar El exprimidor de Johannes?

Regístrate en Exercism para aprender y dominar Crystal con 26 conceptos142 ejercicios y mentoría humana real, todo gratis.