stevan / p5-mop-redux

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

@ISA is not set in `class { ... }` #121

Closed tokuhirom closed 10 years ago

tokuhirom commented 10 years ago
use 5.018000;

use mop;

class Foo {
    sub bark { say "Gah!" }
}

class Bar extends Foo {
    say join(',', @Bar::ISA);
}

say join(',', @Bar::ISA);

It means I can't use __PACKAGE__->foo() style function with mop. It makes hard to migrate to mop.

doy commented 10 years ago

Can you give a real example of what you mean? I'm not sure I follow. Is there a reason you can't run them after the class block? The initial concept is that you shouldn't need to have anything other than has and method declarations inside the class block itself.

tokuhirom commented 10 years ago

I want to write like this.

package Foo extends Framework {
  __PACKAGE__->load_plugins('Foo');
}
stevan commented 10 years ago

We talked about (but haven't written yet) support for __CLASS__, which would be the replacement for __PACKAGE__.

I suspect though that you could do this as a trait, something like:

class Foo extends Framework is pluggable('Foo') {}

Where pluggable might look something like:

sub pluggable {
    my ($class, @args) = @_;
    die "pluggable only accepts class object" if not $class->isa('mop::class');
    $class->load_plugins( @args );
}
tokuhirom commented 10 years ago

Hm. My first first impression about this is "Why mop.pm does not set @ISA before class block? Though it looks like an easy thing.". If you can not do it as a thought, it is not a problem at present.

doy commented 10 years ago

__CLASS__ actually is already supported. It may be possible to support this use case too - we could run traits and FINALIZE after compile time of the class block instead of after runtime of the class block, since has and method do all of their work at compile time (the class block itself would still run at compile time of the overall script). That may be something worth considering.

stevan commented 10 years ago

@doy, perhaps, but I still think this would be better as a trait :)

doy commented 10 years ago

It probably would, but some existing frameworks (DBIx::Class, for instance) do document an interface like this - it'd be nice if we could provide something as similar as possible to the existing code, along the lines of:

class MyApp::Schema extends DBIx::Class::Schema is extending_non_mop {
    __CLASS__->load_namespaces;
    ...
}

rather than requiring all of these existing things to use weird shims.

stevan commented 10 years ago

@doy, agreed, but we should also encourage breaking of those awkward idioms now that we have a proper mechanism instead

doy commented 10 years ago

Yes, this should primarily be a back-compat thing.

doy commented 10 years ago

This is now working - see https://github.com/stevan/p5-mop-redux/blob/xs/t/110-oddities/018-class-block-code.t for an example. Thanks!