Crystal 0.20.5 (2017-01-25)
class Example
property array : Array(String)
def insert(text : String)
@array << text
end
def show
p @array
end
end
init = Example.new
init.insert("Hello World!")
init.show
Result:
laptop% crystal build ./checker.cr
Error in checker.cr:38: expanding macro
property array : Array(String)
^
in macro 'property' expanded macro: macro_62182160:567, line 4:
1.
2.
3.
> 4. @array : Array(String)
5.
6. def array : Array(String)
7. @array
8. end
9.
10. def array=(@array : Array(String))
11. end
12.
13.
14.
15.
instance variable '@array' of Example was not initialized in all of the 'initialize' methods, rendering it nilable
Or
class Example
property! array : Array(String)
def insert(text : String)
@array << text
end
def show
p @array
end
end
init = Example.new
init.insert("Hello World!")
init.show
Result:
laptop% crystal build ./checker.cr
Error in checker.cr:55: instantiating 'Example#insert(String)'
init.insert("Hello World!")
^~~~~~
in checker.cr:45: undefined method '<<' for Nil (compile-time type is (Array(String) | Nil))
@array << text
^~
Rerun with --error-trace to show a complete error trace.
But this code works:
class Example
def initialize
@array = [] of String
end
def insert(text : String)
@array << text
end
def show
p @array
end
end
init = Example.new
init.insert("Hello World!")
init.show
Result:
laptop% crystal build ./checker.cr
laptop% ./checker
["Hello World!"]
i don't understand, why it's doesn't work with property? :-(
In the following class:
class Example
property array : Array(String)
def insert(text : String)
@array << text
end
def show
p @array
end
end
you did not provide an initialize method that defines @array's value when constructed (or otherwise provide a default value, see below) so here:
init = Example.new
@array would be nil... however, your type restriction of Array(String) does not allow it to be Nil - and the compiler warns you of this.
Consider this, which will default new instances of Example as an empty array instead of Nil.
class Example
property array = [] of String
def insert(text : String)
@array = [text]
end
def show
p @array
end
end
Most helpful comment
In the following class:
you did not provide an
initializemethod that defines@array's value when constructed (or otherwise provide a default value, see below) so here:init = Example.new@arraywould benil... however, your type restriction ofArray(String)does not allow it to beNil- and the compiler warns you of this.Consider this, which will default new instances of
Exampleas an empty array instead ofNil.