There are two things here. First, it’s OK for the code not to compile because when you include a module only the instance type gets included, so technically the Bar class is not a Foo class. You can see this is like that because you can’t invoke class methods of Foo from Bar.
module Foo
def self.foo
1
end
end
class Bar
include Foo
end
Bar.foo # undefined method 'foo' for Bar.class
However, I think it should work when extending the module… but it doesn’t.
Also, as @bcardff says, all of this hasn’t been well defined yet.
That’s interesting. However, even when extending, it doesn’t work as well (https://carc.in/#/r/5wyg):
module Foo
end
class Bar
extend Foo
end
ary = Array(Foo.class).new
ary << Bar
Error in line 9: no overload matches 'Array(Foo:Module)#<<' with type Bar.class
Overloads are:
- Array(T)#<<(value : T)
Nevertheless, my use-case is Event-Driven Architecture (EDA), where a number of subscribers can subscribe to an Event. For performance benefit, it’s smart to store them in a Hash(Event.class, Array(Proc(Event, Nil)) for faster reaction times. Currently the code looks like this:
struct MyEvent < Event
getter foo
def initialize(@foo : String)
end
end
channel.subscribe(MyEvent) { |event| do_something(event.foo) }
It works nicely when Event is abstract struct, but I’d like to make it a module – just for more beautiful (subjectively) code.
Summing it up, Hash(Event.class, Proc(Event, Nil)) doesn’t work when Event is a module, as well as Set(Event.class) and Array(Event.class), as stated in the first post.
Okay, as always, after posting I understand that module would not work for me in my case because all_subclasses for a module doesn’t make sense. And I need to know subclasses for my arch.
However, the issue still remains, and I cannot use a module Foo's includer in the place of Foo.class.