Open dorianmariecom opened 2 years ago
Recursive aliases are broken in many ways (ref #5155). This is nevertheless a valid compiler bug. The compiler should not segfault on a recursive alias. But it's probably never going to work.
I'd strongly advise against using them. They can usually be very easily replaced by a simple struct wrapper (see #5155 and https://github.com/crystal-lang/crystal/pull/5183 for an example).
Thanks, I basically copied the json module and did:
class Language
class Output
def_clone
alias Type = String | Hash(Symbol, Output)
getter raw : Type
def initialize(@raw : Type = "")
end
def ==(other : Output)
raw == other.raw
end
def ==(other)
raw == other
end
def pretty_print(pp)
raw.pretty_print(pp)
end
def to_s(io)
raw.to_s(io)
end
def inspect(io)
raw.inspect(io)
end
end
end
class Object
def ===(other : Language::Output)
self === other.raw
end
end
struct Value
def ==(other : Language::Output)
self == other.raw
end
end
class Reference
def ==(other : Language::Output)
self == other.raw
end
end
class Array
def ==(other : Language::Output)
self == other.raw
end
end
class Hash
def ==(other : Language::Output)
self == other.raw
end
end
class Regex
def ===(other : Language::Output)
value = self === other.raw
$~ = $~
value
end
end
And when I use it:
def aka(name)
if @buffer.empty?
@output = Output.new({name => @output})
else
@output = Output.new({name => Output.new(@buffer)})
@buffer = ""
end
end
I still think it would be simpler if recursive types were properly supported
I tried to do:
Because I wanted to do
@output = { name => @output }
.That lead to:
https://github.com/dorianmariefr/language/tree/crystal-recursive-type