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)