Os getters e os setters são métodos que te permitem ler e escrever o valor de uma propriedade de um objeto. O Crystal tem macros, o que torna mais fácil definir getters e setters para uma propriedade. As macros são uma forma de gerar código em tempo de compilação, algo que será abordado mais à frente no conceito de macros.
Em Ruby, estes métodos são definidos com os métodos attr_reader, attr_writer e attr_accessor e, à superfície, são muito semelhantes à implementação do Crystal.
O Crystal definiu-os como as macros getter, setter e property.
Getter é uma macro que define um método que devolve o valor de uma variável de instância.
Isto significa que já não precisas de escrever @ antes da variável de instância quando queres aceder-lhe (em métodos, exceto no initialize); em vez disso, podes chamar o método que a macro getter definiu.
A macro getter pode aceitar várias variáveis de instância, separando-as por vírgulas.
# 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 podes ver, usar getter reduz a quantidade de código que escreves e torna-o mais fácil de ler. Além disso, o Ruby e o Crystal diferem no facto de o Crystal aceitar tanto o nome da variável como o símbolo como argumentos para a macro getter. Os símbolos serão abordados mais à frente no conceito de símbolos.
Setter é uma macro que define um método que atribui o valor a uma variável de instância.
Esta macro não é muito comum e, em vez dela, costuma usar-se a macro property.
Os métodos criados terão o aspeto name_of_method=; é o = que faz com que a propriedade possa ser definida.
Esta definição de método é um pouco especial, pois o argumento que o método recebe vem depois do sinal =.
Vários outros métodos especiais do Crystal usam esta sintaxe, como o método +.
Tal como acontece com a macro getter, quando queres atualizar o valor de uma variável de instância depois de definires um setter, podes chamar o método que a macro setter definiu.
# 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 é uma macro que define tanto um getter como um setter para uma variável de instância.
class Person
@name : String
@age : Int32
property name, :age
end
Neste exercício vais modelar uma máquina de pesagem.
Quando é inicializada, a máquina de pesagem deve usar as suas configurações de fábrica, que são diferentes consoante o sítio onde a máquina é vendida. Além disso, a máquina deve poder ser inicializada com uma precisão e com a indicação de se usa o sistema métrico ou o imperial.
Implementa o método WeighingMachine#initialize, que recebe dois argumentos: precision, que é um Int32, e metric, que é um Bool. O argumento metric, quando é true, significa que a máquina deve usar o sistema métrico; caso contrário, deve usar o sistema imperial. O método initialize também deve definir a variável de instância @weight como 0.0.
precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)
Para responder a exigências diferentes, permitimos que cada máquina de pesagem seja personalizada com uma precisão (o número de algarismos depois do separador decimal).
Implementa o método getter WeighingMachine#precision para devolver a precisão da máquina de pesagem.
precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)
vm.precision
# => 3
Implementa a propriedade WeighingMachine#weight para permitir obter e definir o peso:
precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
wm.weight = 60.5
wm.weight
# => 60.5
wm.weigh
# => 60.5
Implementa a propriedade WeighingMachine#metric= para permitir definir a unidade. Deve aceitar um valor do tipo Boolean.
precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
vm.weight = 60.5
wm.metric = false
vm.weigh
# => 133.377
Inscreve-te no Exercism para aprenderes e dominares Crystal com 26 conceitos142 exercícios, e mentoria humana real, tudo grátis.