Search code examples
crystal-lang

Looking for a way to hold a reference to a class so that I can dynamically instantiate it later


I've created this playground which should make my question more clear but in a nutshell, I'm looking for a way to pass a reference to a class name to another class's initializer so that at a later stage in the compilation process I can instantiate that class and do something with it.

class Route
  property action : Class

  def initialize(@action)
  end

  def do_something
    @action.new.call
  end
end

class Action
  def call
    puts "called"
  end
end

route = Route.new(Action)

however, the above gives me can't use Object as the type of an instance variable yet, use a more specific type

I understand this is something that might not yet be implemented in the language but I was wondering if there was another way to achieve this seeing as I can't really do as the error suggested and be more specific because I need to accept any class.

Hoping someone will be able to point me in the right direction...

Thanks in advance!


Solution

  • Try generics:

    Crystal, 233 bytes

    class Route(T)
      property action : T
    
      def initialize(@action)
      end
    
      def do_something
        @action.new.call
      end
    end
    
    class Action
      def call
        puts "called"
      end
    end
    
    route = Route(Action.class).new(Action)
    route.do_something
    

    Try it online!