earl icon indicating copy to clipboard operation
earl copied to clipboard

`Earl::Artist(AbstractType)` raises `#call(AbstractType) must be defined`

Open y8 opened this issue 1 year ago • 3 comments

This example fails to compile with Error: method Bar#call(AbstractMessage) must be defined:

require "earl/artist"

abstract struct AbstractMessage
end

record FooMessage < AbstractMessage

module Foo
  macro included
    include Earl::Artist(AbstractMessage)
  end

  def call(event : FooMessage)
    p "event: #{event}"
  end
end

class Bar
  include Foo
end

bar = Bar.new
bar.spawn
bar.send FooMessage.new

sleep

But there is call(event : FooMessage) implementation in module Foo so it should not raise the error.

y8 avatar Oct 25 '23 08:10 y8

Oh, this may be my custom macro to circumvent a crystal limitation that's failing because FooMessage is a descendant of AbstractMessage while the macro expects an AbstractMessage.

See https://github.com/ysbaddaden/earl/blob/3f4c145e11946eaa137c8bd42ddd1d1cb46bfc5d/src/artist.cr#L26-L68

If you want to have a look: The includes? are most likely at fault (they expect the exact type. Maybe the whole macro isn't working for different other edge cases...

ysbaddaden avatar Oct 26 '23 18:10 ysbaddaden

Yeah, I've figured about this macro

The includes? are most likely at fault (they expect the exact type

In this case macro should look if particular class implements overloads for all AbstractMessage subclasses and raise pricing ones that are not implemented, right?

y8 avatar Nov 03 '23 16:11 y8

Yeah, for each possible type, the macro should check that there is an overload with that explicit type (in which case the type + all its descendant types are fully implemented) or if all its descendant types have an overload (in which case the type is fully implemented).

But that will start to be a bit complex (a type can have a tree of descendants) :fearful:

ysbaddaden avatar Nov 03 '23 16:11 ysbaddaden