The following (reduced) example:
class Foo
end
class Bar < Foo
end
class Baz < Foo
end
alias ProcType = Proc(Foo)
class Qux
property test : ProcType
def initialize(@test)
end
end
def a
Bar.new
end
def b
Baz.new
end
Qux.new(->a)
Qux.new(->b)
produces the following error message:
Error in ./test.cr:27: instantiating 'Qux:Class#new(Proc(Bar))'
Qux.new(->a)
^~~
in ./test.cr:15: instantiating 'Qux#initialize(Proc(Bar))'
def initialize(@test)
^
in ./test.cr:15: instance variable '@test' of Qux must be Proc(Foo), not Proc(Bar)
def initialize(@test)
^~~~~
I'm on Crystal 0.19.4 (2016-10-21) on macOS Sierra 10.12.1
I'm expecting this to work because Bar is a subclass of Foo and ProcType asks for a value of type Foo.
Is this a bug / missing feature or am I just missing something?
Yeah, that should probably work (passing a proc with a stronger return type)
Until this is fixed, I found a way to work around this issue:
alias ProcType = Proc(Foo) | Proc(Bar) | Proc(Baz)
You just have to repeat this for every class / subclass you want to support.
You can also use .as(Foo) as a workaround.
@RX14 true, although you might want to get back Bar or Baz and do the casting just for the Proc.
Just expanding on @RX14:
class Qux
property test : ProcType
def initialize(test)
@test = ->{test.call.as(Foo)}
end
end
Most helpful comment
Just expanding on @RX14: