When port a big (code is not familiar) Ruby gem into Crystal, a rather annoying thing is that, hundreds of empty {} and , It’s hard to figure out the real type is if just take a quick look, But no type in empty , {} is syntax error, quite annoying.
Same things happen on Dart, but, dart handle this use a special dynamic type can be used replace any type., when user user it, user is responsible for the null safety, but code is working, without error, the downside is some editor autocomplete missing.
so, is there exist a type can be used to as this role?
e.g. i can replace all occur of x = [] into x = [] of Dynamic, y = {} into y = {} of Dynamic => Dynamic to workaround the syntax error, then i will replace Dynamic into the really type smoothly.
Hi, @asterite any better advice for use a special type as the default placeholder?
what i means is, a type that is rarely used directly by users(rarely appears in errors backtrace), i can replace {} with: {} of RareType => RareType use port_ruby_to_crystal tool.
then, when this type show in the error message, i can know i set a wrong type as placeholder.
anyway, this is a intermediate step for avoid the syntax error of empty hash/array in Ruby, less friction.
Wouldn’t it be better for this use case to just leave the untyped hash literal? Then the compiler’s syntax error directly points you to where you need to manually give some type information.
I just want a builtin Type, e.g. used by compiler, almost never used directly by users, as a empty array/hash’s default type, then, once the code has no syntax errors, i can use type inference to guess the correct type, then replace it back.
class BlackHole
macro method_missing(call)
raise "BUG: must implement {{call.name}}"
end
end
array = BlackHole.new
array << 1
array << "hello"
puts array.size
array.each do |x|
puts x
end
Such type will never make it to the standard library, though.
I probably still explain my thought clearly, sorry, maybe this just an unreasonable demand?
I really want to do is, when i am porting a big ruby gem, replace all ary = [], h = {} with ary = [] of SomeType, h = {} of SomeType => SomeType use a tools, after then, when i run replaced ruby code use crystal, no syntax anymore, instead of, only compiler error left, which can lead me to find the correct type of the ary and h.
So, here, when i am replaceing code, the SomeType is important, It must be a valid builtin Crystal Type, but, rarely used by the user directly, which give a sign like this when build the code, like this:
Oops, then i will know, i should replace
arry = [] of SomeType
into
arry = [] of Procodile::Instance.
If i am not add this Intermediate step instead, only give me syntax like: Error: for empty arrays use '[] of ElementType', without any additional help for figure out what arry type is.
There doesn’t exist any one for all kind of type in Crystal. For porting projects, one should first have a better understanding of code before starting the port process, in that way one will know before hand what kind of objects are going to be stored in those containers.
2nd for your use case you can always start with union types of some general types which you believe are quite normal in that gem which you are porting, and once done with migration you can restrict that type to be something more specific or concise.
alias SomeType = String | Int32 | Float64 | Nil | MyAweSomeType
arr = [] of SomeType
hsh = {} of SomeType => SomeType
.......