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