Crystal: Undefined method '<<' for Nil

Created on 19 Mar 2017  路  1Comment  路  Source: crystal-lang/crystal

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? :-(

question

Most helpful comment

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

>All comments

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
Was this page helpful?
0 / 5 - 0 ratings