We can simplify our constructor by using a shorter syntax for assigning a method argument 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.
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
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 the same arguments as the method's arguments. Otherwise, it receives the arguments you pass to it.
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/docs/syntax_and_semantics/methods_and_instance_variables.html