Today I played around with Crystal... the programming language (π₯ ba-dum-tss).
Coming from Ruby, Crystal isn't a mystery in many cases, but in the end, I don't know much about it at all.
However, I learned something about Tuples and Arrays today.
It starts simple with a class that takes a String as an argument.
class TupleVsArray
  def initialize(@text : String)
    puts "Text: #{@text}"
  end
end
Now let's decomposit an array into two variables, and then pass the first variable, foo, into the class:
foo, bar = ["foo", "bar"]
TupleVsArray.new(foo)     # Text: foo
This works fine.
All elements in the array are of type String.
It compiles, it runs!
Let's change the second element in the array into a Symbol:
foo, bar = ["foo", :bar]
TupleVsArray.new(foo)
This fails during compiling with this error:
Error: no overload matches 'TupleVsArray.new' with type (String | Symbol)
To me, having little to 0 experience with type checking, this is fascinating... and confusing, because foo is allegedly never going to be a Symbol. Allegedly...
Then I realized that the array could be changed in the meantime, for example:
row = ["foo", :bar]
row[0] = :foo
foo, bar = row
TupleVsArray.new(foo)
# Error: no overload matches 'TupleVsArray.new' with type (String | Symbol)
This time, the error makes absolutely sense.
Then I also learned, that in Crystal we cannot change an array's element to an not-yet-existing type:
row = ["foo", :bar]
row[0] = 42
Error: no overload matches '=' with types Int32, Int32
If we want to change any element in row, we must only use String or Symbol.
So, in order to resolve the original problem, we need to use a Tuple, which is a
[...] fixed-size, immutable, stack-allocated sequence of values of possibly different types.
foo, bar = {"foo", :bar}
TupleVsArray.new(foo)     # Text: foo
Alright, got it. π
(Photo by Cristofer Jeschke on Unsplash)
 
 
              
 
    
Top comments (0)