More MOP related questions :)

In the p5 MetaModel, you can do the following:

$obj->meta->add_method('foo' => Perl6::Method->create_instance_method(sub { ... })); $obj->meta->add_method('foo' => Perl6::Method->create_class_method(sub { ... })); $obj->meta->add_method('foo' => Perl6::Method->create_submethod(sub { ... })); $obj->meta->add_method('foo' => Perl6::Method->create_private_method(sub { ... }));

<quick aside for clarity>

The Perl6::Method package is really just a closure generator. It takes a chunk of code (a sub {} ref) and wraps it with the appropriate wrapper based on the type of "method-thing" you request. It currently handles instance methods, class methods, private methods and submethods. The details of this are not really relevant to this discussion though, I just wanted to answer what I saw as an inevitable question.

</quick aside for clarity>

Now I realize that in perl 6 you can re-open classes and add methods to them. However this is not convenient for programmatic class generation. And I would really prefer the old Perl 5 way of mucking with the symbol table not be the Perl 6 way of doing this. The ideal approach IMO is to be able to do what the p5 MetaModel prototype does, and be able to add methods to the metaclass instance directly (which then exposes them to the class and instances of the class).

So, how should this look in Perl 6? I currently have a two thoughts/suggestions/directions.

1) Anonymous methods/submethods

$obj.meta.add_method('foo' => method (Foo $self: $bar) { ... }); # adding an instance method $obj.meta.add_method('foo' => method (::Foo $class: $bar) { ... }); # adding a class method $obj.meta.add_method('foo' => submethod ($self: $bar) { ... }); # adding a submethod method $obj.meta.add_method(':foo' => method ($self: $bar) { ... }); # adding a private method (NOTE: ':' in name)

I am not sure if anonymous methods have been discussed already or not. But this is one possible approach. The idea being that since it is a method already, it would already know about things like $?SELF, $?CLASS and next METHOD (although those values would be unbound), and would likely have an invocant parameter (which could sometimes be used to determine if it was a class method or instance method).

2) Closure factory

$obj.meta.add_method('foo' => sub ($self, $bar) { ... }, :type<instance>);
$obj.meta.add_method('foo' => sub ($self, $bar) { ... }, :type<class>);
$obj.meta.add_method('foo' => ($self, $bar) -> { ... }, :type<submethod>);
$obj.meta.add_method(':foo' => { ... }, :type<private>);

Given an arbitrary block of executable code (anything from a raw block, to a pointy block, to a sub ref) the add_method closure factory will turn it into the right "method-thing" based upon the :type<> parameter.

Thoughts??

Thanks,

Stevan


Reply via email to