I want to create a hash in which I register classes that implement operators in a programming language. Each operator has its own class definition. The class has methods that return type and argument-type information, and I want to know this information before instantiating an object of that class. So, I would like to get the Class object from my registration system.
I can’t create Hash(String, Class)
because Class can’t be used as a generic type parameter yet.
I can’t create Proc(Nil, Class)
for the same reason.
I have macros that will register all non-abstract derivatives of a class automatically, if only I can arrive at the type of the registration hash.
1 Like
Usually the way you handle this is you type it to some module/parent type (or refactor things so you don’t need to do this). Something like https://play.crystal-lang.org/#/r/9kme.
What would an example value of the key be in this context? Sounds like you’re making some DI system? If so you could checkout https://athena-framework.github.io/dependency-injection/Athena/DependencyInjection.html.
1 Like
[Edit: almost the same as said by @Blacksmoke16]
If you have a common type of the classes you want to register you can use Hash(String, Common.class)
. This is similar to how crystal-db register a Driver class per uri scheme.
Another similar approach is using modules and make class extend from them. That creates a union of the classes.
The following compiles
module Common
abstract def description
abstract def make(v)
end
struct Int32
extend Common
def self.description
"I create Int32"
end
def self.make(v)
raise "not int32"
end
def self.make(v : Int32)
v
end
end
class String
extend Common
def self.description
"I create String"
end
def self.make(v)
raise "not string"
end
def self.make(v : String)
v
end
end
h = {} of String => Common
h["int"] = Int32.as(Common)
h["string"] = String.as(Common)
a = h["int"].make(4)
pp!({a, typeof(a), a.class})
b = h["string"].make("str")
pp!({b, typeof(b), b.class})
h["int"].make("str") rescue puts "ERROR: int from str"
h["string"].make(4) rescue puts "ERROR: str from int"
pp! h["int"].description
pp! h["string"].description
1 Like
Thank you both, both of the methods you have suggested work.
1 Like