Methods and instance variables
We can simplify our constructor by using a shorter syntax for assigning a method parameter to an instance variable:
class Person
def initialize(@name : String)
@age = 0
end
def age
@age
end
end
Right now, we can't do much with a person aside from create it with a name. Its age will always be zero. So lets add a method that makes a person become older:
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
Method names begin with a lowercase letter and, as a convention, only use lowercase letters, underscores and numbers.
Getters and setters
The Crystal Standard Library provides macros which simplify the definition of getter and setter methods:
class Person
property age
getter name : String
def initialize(@name)
@age = 0
end
end
john = Person.new "John"
john.age = 32
john.age # => 32
For more information on getter and setter macros, see the standard library documentation for Object#getter, Object#setter, and Object#property.
As a side note, we can define become_older
inside the original Person
definition, or in a separate definition: Crystal combines all definitions into a single class. The following works just fine:
class Person
def initialize(@name : String)
@age = 0
end
end
class Person
def become_older
@age += 1
end
end
Redefining methods, and previous_def
If you redefine a method, the last definition will take precedence.
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
You can invoke the previously redefined method with 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
Without arguments or parentheses, previous_def
receives all of the method's parameters as arguments. Otherwise, it receives the arguments you pass to it.
Catch-all initialization
Instance variables can also be initialized outside initialize
methods:
class Person
@age = 0
def initialize(@name : String)
end
end
This will initialize @age
to zero in every constructor. This is useful to avoid duplication, but also to avoid the Nil
type when reopening a class and adding instance variables to it.
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/syntax_and_semantics/methods_and_instance_variables.html