Методы и переменные экземпляра
Мы можем упростить конструктор, используя сокращённый синтаксис для присваивания параметра метода переменной экземпляра:
class Person
def initialize(@name : String)
@age = 0
end
def age
@age
end
end
Пока что мы можем сделать с человеком немногое: только создать его, указав имя. Его возраст всегда будет равен нулю. Добавим метод, который будет увеличивать возраст человека:
class Person
def initialize(@name : String)
@age = 0
end
def age
@age
end
def become_older
@age += 1
end
end
john = Person.new "John"
peter = Person.new "Peter"
john.age # => 0
john.become_older
john.age # => 1
peter.age # => 0
Имена методов начинаются со строчной буквы и, согласно соглашению, содержат только строчные буквы, символы подчёркивания и цифры.
Геттеры и сеттеры
Стандартная библиотека Crystal предоставляет макросы, упрощающие определение методов-геттеров и методов-сеттеров:
class Person
property age
getter name : String
def initialize(@name)
@age = 0
end
end
john = Person.new "John"
john.age = 32
john.age # => 32
Подробнее о макросах геттеров и сеттеров см. в документации стандартной библиотеки: Object#getter, Object#setter и Object#property.
К слову, мы можем определить become_older внутри исходного определения Person или в отдельном определении: Crystal объединяет все определения в один класс. Следующий вариант работает без проблем:
class Person
def initialize(@name : String)
@age = 0
end
end
class Person
def become_older
@age += 1
end
end
Переопределение методов и previous_def
При переопределении метода приоритет имеет последнее определение.
class Person
def become_older
@age += 1
end
end
class Person
def become_older
@age += 2
end
end
person = Person.new "John"
person.become_older
person.age # => 2
Вызвать метод, который был определён до переопределения, можно с помощью previous_def:
class Person
def become_older
@age += 1
end
end
class Person
def become_older
previous_def
@age += 2
end
end
person = Person.new "John"
person.become_older
person.age # => 3
Если не передавать аргументы и не использовать скобки, previous_def получит все параметры метода в качестве аргументов. В противном случае он получит переданные ему аргументы.
Универсальная инициализация
Переменные экземпляра также можно инициализировать вне методов initialize:
class Person
@age = 0
def initialize(@name : String)
end
end
Так переменная @age будет инициализирована нулём в каждом конструкторе. Это позволяет избежать дублирования кода, а также типа Nil при повторном открытии класса и добавлении в него переменных экземпляра.
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/methods_and_instance_variables.html