Gmane
From: Stevan Little <stevan <at> iinteractive.com>
Subject: $obj.meta.add_method('foo' => ???)
Newsgroups: gmane.comp.lang.perl.perl6.language
Date: 2005-08-09 22:32:52 GMT (3 years, 47 weeks, 1 day, 5 hours and 40 minutes ago)
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