Báscula

Báscula

Ejercicio de aprendizaje

Introducción

Los getters y los setters son métodos que te permiten leer y escribir el valor de una propiedad de un objeto. Crystal tiene macros, lo que facilita definir getters y setters para una propiedad. Las macros son una forma de generar código en tiempo de compilación, algo que se tratará más adelante en el concepto de macros.

En Ruby, estos métodos se definen con los métodos attr_reader, attr_writer y attr_accessor, y en apariencia son muy similares a la implementación de Crystal. Crystal los ha definido como las macros getter, setter y property.

Getters

Getter es una macro que define un método que devuelve el valor de una variable de instancia. Esto significa que ya no tienes que escribir @ delante de la variable de instancia cuando quieras acceder a ella (en los métodos, excepto en initialize); en su lugar, puedes llamar al método que ha definido la macro getter.

La macro getter puede aceptar varias variables de instancia separándolas con comas.

# This:
class Person
  @name : String
  @age : Int32

  def name
    @name
  end

  def age
    @age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  getter name, :age
end

Como puedes ver, usar getter reduce la cantidad de código que escribes y hace que sea más fácil de leer. Además, Ruby y Crystal se diferencian en que Crystal acepta tanto el nombre de la variable como un símbolo como argumentos para la macro getter. Los símbolos se tratarán más adelante en el concepto de símbolos.

Setters

Setter es una macro que define un método que asigna el valor de una variable de instancia. Esta macro no se ve muy a menudo y, en su lugar, se suele usar la macro property. Los métodos que se creen tendrán un aspecto como name_of_method=; el = es lo que permite que la propiedad se pueda asignar.

Esta definición de método es un poco especial, ya que el argumento que recibe el método va después del signo =. Otros métodos especiales de Crystal usan esta sintaxis, como el método +.

Al igual que con la macro getter, cuando quieras actualizar el valor de una variable de instancia después de definir un setter, puedes llamar al método que ha definido la macro setter.

# This:
class Person
  @name : String
  @age : Int32

  def name=(name : String)
    @name = name
  end

  def age=(age : Int32)
    @age = age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  setter name, :age
end

Property

Property es una macro que define tanto un getter como un setter para una variable de instancia.

class Person
  @name : String
  @age : Int32

  property name, :age
end

Instrucciones

En este ejercicio vas a modelar una báscula.

1. Crea un estado inicial para la báscula

Al inicializarse, la báscula debe remitirse a su configuración de fábrica, que varía según dónde se venda. Por eso, la báscula debe poder inicializarse con una precisión y con si es métrica o imperial.

Implementa el método WeighingMachine#initialize, que recibe dos argumentos: precision, que es un Int32, y metric, que es un Bool. Cuando el argumento metric es true, significa que la báscula debe usar el sistema métrico; de lo contrario, debe usar el sistema imperial. El método de inicialización también debe establecer la variable de instancia @weight a 0.0.

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)

2. Permite que la báscula tenga una precisión

Para atender distintas necesidades, permitimos que cada báscula se personalice con una precisión (el número de dígitos después del separador decimal).

Implementa el método getter WeighingMachine#precision para que devuelva la precisión de la báscula.

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)
vm.precision
# => 3

3. Permite establecer el peso en la báscula

Implementa la propiedad WeighingMachine#weight para permitir obtener y establecer el peso:

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
wm.weight = 60.5
wm.weight
# => 60.5

wm.weigh
# => 60.5

4. Permite cambiar la báscula entre las unidades métrica e imperial

Implementa la propiedad WeighingMachine#metric= para permitir establecer la unidad. Debe aceptar un valor de tipo Boolean.

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
vm.weight = 60.5
wm.metric = false

vm.weigh
# => 133.377
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Crystal Exercism

¿Listo para empezar Báscula?

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