Crystal: Recursive Hash initialization

Created on 2 May 2018  路  8Comments  路  Source: crystal-lang/crystal

Hola,

alias MyHash = Hash(String, String | MyHash)
h = MyHash.new # Doesn't work
h = {} of String => String | MyHash # Works

:bug: ?

All 8 comments

Recursive types are buggy, incomplete and can simply be done with a recursive struct. I said many times "let's remove them from the language", and I think that what will happen, eventually. So try not to use them. You probably don't need them.

Yes let's remove them!

@asterite I need key-value access and merging. Structs are limited in that way

@vladfaust We have no idea what you are trying to implement. But I'm pretty sure it can be done without recursive aliases, because no other language has such feature.

@asterite could you please help me then? I cannot make it work:

struct Param
  @value : String | Int32 | Float64 | Hash(String, Param) | Nil

  def initialize(@value)
  end

  def [](key : String)
    if @value.is_a?(Hash)
      @value.as(Hash)[key]
    else
      raise Exception.new("Cannot call #[] on #{@value.class}")
    end
  end

  def []=(key : String, value)
    if @value.is_a?(Hash)
      @value.as(Hash)[key] = value
    else
      raise Exception.new("Cannot call #[]= on #{@value.class}")
    end
  end
end

params = Param.new({} of String => Param)
params["foo"] = "bar".as(Param)

updated

BTW, why do we need to write .as(Hash) if it's already within if @value.is_a?(Hash) branch?

Param.new("bar")

But sorry, I have no time to do 1on1 support. Better ask in gitter this kind of things.

@asterite you paved me the way. Thanks then, hope this will be helpful to someone!

While I tend to agree that structs are usually the way to go instead of a variable with a recursive type, there are some uses cases that the recursive type makes more sense.

For example, including user context in log messages. Each log event could have its own hash of context, of any type, including a sub hash.

msg.extra["git"] = {"branch" => git_info[1]?, "commit" => git_info[2]?} is a lot more straightforward than using structs from a UX point of view.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xtagon picture xtagon  路  132Comments

chocolateboy picture chocolateboy  路  87Comments

stugol picture stugol  路  70Comments

asterite picture asterite  路  139Comments

akzhan picture akzhan  路  67Comments