stevan / p5-mop-redux

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

Getting the class name I'm compiled into #147

Closed Ovid closed 10 years ago

Ovid commented 10 years ago

This code:

use 5.018;
use mop;

class Foo {
    method my_package { __PACKAGE__ }
}
class Foo::Bar extends Foo {};

my $foo = Foo->new( test => 'this' );
say $foo->my_package;
my $foobar = Foo::Bar->new( test => 'this' );                                                                                                                                                                 
say $foobar->my_package;

Prints main twice. That actually makes sense, but I'm unsure how to figure out the name of the class I'm compiled into. Using mop::meta($self)->name returns the subclass name in Foo::Bar.

Also, I've noticed that when I use Test::Class::MOP::Load (I'm porting Test::Class to p5-mop-redux) to dynamically load the modules via eval "use $package", __PACKAGE__ in Test::Class::MOP returns Test::Class::MOP::Load.

As an aside, I've noticed that extra arguments are silently ignored. I realize this is probably done for performance reasons, but typos will cause issues.

stevan commented 10 years ago

__PACKAGE__ is not supported, you want __CLASS__.

stevan commented 10 years ago

Regarding the silent ignoring of constructor parameters, the same argument as Moose applies here; the arguments to new are passed to BUILD and so can be used for purposes other then attribute initialization.

Ovid commented 10 years ago

For this code:

    state $classes;
    unless ($classes) {
        $classes = [
            sort
            grep { $_ ne __CLASS__ && $_->isa(__CLASS__) }                                                                                                                                                    
            map { s!/!::!g; s/\.pm$//; $_ } keys %INC
        ];
    }

When I try to run it, I get t/basic.t .. Bareword "__CLASS__" not allowed while "strict subs" in use at lib/Test/Class/MOP.pm line 244.

stevan commented 10 years ago

__CLASS__ is only valid inside a class definition.

Ovid commented 10 years ago

You might want to check out method test_classes inside of https://github.com/Ovid/test-class-mop. It's here:

class Test::Class::MOP {
    # lots of code
    method test_classes {
        # __CLASS__ was failing here
    }
    # lots of code
}

Perhaps I missed something?

stevan commented 10 years ago

Hmm, nothing seems wrong, I am unsure why it is failing.

@doy, any thoughts?

Ovid commented 10 years ago

Even stranger. perl -c lib/Test/Class/MOP.pm says it's fine. It's only when I try to do perl t/basic.t (or prove) that this happens:

Bareword "__CLASS__" not allowed while "strict subs" in use at lib/Test/Class/MOP.pm line 241.
Bareword "__CLASS__" not allowed while "strict subs" in use at lib/Test/Class/MOP.pm line 241.
Compilation failed in require at t/lib/TestsFor/Basic.pm line 2.
BEGIN failed--compilation aborted at t/lib/TestsFor/Basic.pm line 2.
Compilation failed in require at (eval 27) line 1.
BEGIN failed--compilation aborted at (eval 27) line 1.
BEGIN failed--compilation aborted at t/basic.t line 4.
Ovid commented 10 years ago

To replicate this bug, eval a class into existence either by eval'ing it or 'eval "use $class" (using a class directly is fine). The class must contain a __CLASS__ token and you must not be in main:: when you eval. A test for this is in the following pull request: https://github.com/stevan/p5-mop-redux/pull/150

doy commented 10 years ago

This is another issue similar to the method method { } stuff we were running into earlier. It should also be fixed when we get lexical keywords working.

doy commented 10 years ago

This can be closed in favor of #150.