Search code examples
crystal-lang

Define instance method with "macro inherited" in Crystal 0.21.1


As I understand it the type declaration works like kind_of

“So types aren't strictly the type named but rather act like a is_a? or kind_of?.” https://github.com/crystal-lang/crystal/issues/4232

So I think that part of this code works.

But when I use a macro to define an instance method on an inherited class the error message complains about the method missing from the wrong object.

class Base
  macro inherited
    def name
      "Joe Smith"
    end
  end
end

class Context < Base; end

class Render
  def initialize(@inner_context : Base); end

  def display
    name
  end

  forward_missing_to inner_context

  private property inner_context
end

puts Render.new(Context.new).display

And the output is:

Error in line 23: instantiating 'Render#display()'

in line 15: instantiating 'name()'

in macro 'forward_missing_to' /usr/lib/crystal/object.cr:1132, line 1:

>  1.     macro method_missing(call)
   2.       inner_context.{{call}}
   3.     end
   4.   

expanding macro
in macro 'method_missing' expanded macro: forward_missing_to:1, line 1:

>  1.       inner_context.name
   2.     

undefined method 'name' for Base (compile-time type is Base+)

What am I missing here?


Solution

  • @inner_context could be of type Base, which doesn't define a base method.

    One solution is to mark Base as abstract: abstract class Base.