Search code examples
crystal-lang

Curly bracket constructors?


While reading through the Crystal docs, I came across this line:

 deq = Deque{2, 3}

So I think this calls the Deque.new(array : Array(T)) constructor. However, I did not find any documentation about this syntax whatsoever. (EDIT: The documentation can be found here)

To test this way of calling constructors, I wrote the following test

class Foo(T)
  def initialize(@bar : Array(T)); end

  def to_s(io : IO)
    io << "Foo: "
    io << @bar
  end
end

puts Foo{1} # Line 10

But, compiling it prints this error:

Error in line 10: wrong number of arguments for 'Foo(Int32).new' (given 0, expected 1)
Overloads are:
 - Foo(T).new(bar : Array(T))

Which I really don't understand at all. Foo(Int32){1} Raises the same error.

Question is, what is this Klass{1, 2, 3} syntax? And how do you use it?


Solution

  • They are documented here: https://crystal-lang.org/docs/syntax_and_semantics/literals/array.html


    Array-like Type Literal

    Crystal supports an additional literal for arrays and array-like types. It consists of the name of the type followed by a list of elements enclosed in curly braces ({}) and individual elements separated by a comma (,).

    Array{1, 2, 3}
    

    This literal can be used with any type as long as it has an argless constructor and responds to <<.

    IO::Memory{1, 2, 3}
    Set{1, 2, 3}
    

    For a non-generic type like IO::Memory, this is equivalent to:

    array_like = IO::Memory.new
    array_like << 1
    array_like << 2
    array_like << 3
    

    For a generic type like Set, the generic type T is inferred from the types of the elements in the same way as with the array literal. The above is equivalent to:

    array_like = Set(typeof(1, 2, 3)).new
    array_like << 1
    array_like << 2
    array_like << 3
    

    The type arguments can be explicitly specified as part of the type name:

    Set(Number) {1, 2, 3}