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.
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.
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 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
En este ejercicio vas a modelar una 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)
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
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
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
Regístrate en Exercism para aprender y dominar Crystal con 26 conceptos142 ejercicios y mentoría humana real, todo gratis.