stevan / p5-mop-redux

A(nother) MOP for Perl 5
139 stars 36 forks source link

how important are ->isa checks on metaclasses? #74

Open doy opened 11 years ago

doy commented 11 years ago

Given this code:

class MetaFoo extends mop::class { }
class MetaBar extends mop::class { }
class Foo meta MetaFoo { }
class Bar extends Foo meta MetaBar { }

we end up with a situation where the linear isa of Bar's metaclass is ["mop::rebased::MetaBar", "MetaFoo", "mop::class"]. What this means is that mop::get_meta('Bar')->isa('MetaFoo') is true, but mop::get_meta('Bar')->isa('MetaBar') is false. This is fixable, but it would be a bit more effort than I'd like, since we don't have multiple inheritance. The question is, do we care about this? The equivalent code using metaroles does work:

role MetaFooRole { }
role MetaBarRole { }
class MetaFoo extends mop::class with MetaFooRole { }
class MetaBar extends mop::class with MetaBarRole { }
class Foo meta MetaFoo { }
class Bar extends Foo with MetaBar { }

Here, mop::get_meta('Bar')->does('MetaFooRole') and mop::get_meta('Bar')->does('MetaBarRole') are both true. Is this sufficient, or does this need to work with isa too?

stevan commented 10 years ago

I think the solution here is to override isa in mop::rebased::MetaBar such that it will respond correctly to ->isa('MetaBar')

doy commented 10 years ago

The problem with just overriding isa is that overriding a method means modifying the class of the metaclass instance (so we'd need to change mop::get_meta(mop::get_meta('Bar')) as well as mop::get_meta('Bar')). This is doable, but it is an extra layer of complexity.

doy commented 10 years ago

I'm going to make a decision and say that checking ->isa for custom metaclasses is not something that we're going to support (at least for now). If you need an identity check, you should use a role instead. If this turns out to cause actual problems in the future, we can always change it (just leave it as "undefined behavior" for now). I'll leave this open so that we remember to document it.