Search code examples
crystal-lang

Can I name a type in Crystal for convenience?


In my new crystal project, I have a class which is storing its data in a couple of different ways that are useful to me later, both as hashes.

getter isometry_cardinality : Hash(IsometryKind, Int8)
getter axis_cardinality : Hash(Directions::Orientation, Array(IsometryKind))

I'd like to overload my methods now based on which hash its using:

private def has_min_cardinality?(parent_cardinality : Hash(IsometryKind, Int8))
  ...
end

private def has_min_cardinality?(parent_cardinality : Hash(Directions::Orientation, Array(IsometryKind))
  ...
end

as you can see, that declaration is getting pretty long. Is there some convenient way to shorten it? For example, can I use the getter as an alias for its type?

private def has_min_cardinality?(parent_cardinality : isometry_cardinality)
  ...
end

private def has_min_cardinality?(parent_cardinality : axis_cardinality)
  ...
end

The answer is 'no' to that specific example, so my question is: am I missing the right way to do this?


Solution

  • Yes, there is a better way: alias to the rescue!

    You can alias complex types like in this example and use the alias, the compiler just replaces it outright so there's no performance penalty.

    alias IsometryCardinality = Hash(IsometryKind, Int8)
    alias AxisCardinality = Hash(Directions::Orientation, Array(IsometryKind))
    getter isometry_cardinality : IsometryCardinality
    getter axis_cardinality : AxisCardinality
    ...
    private def has_min_cardinality?(parent_cardinality : IsometryCardinality)
      ...
    end
    
    private def has_min_cardinality?(parent_cardinality : AxisCardinality)
      ...
    end
    

    Here's a demo: https://play.crystal-lang.org/#/r/4hoh