Runtime role issues

0 views
Skip to first unread message

Ovid

unread,
Oct 11, 2006, 6:44:37 AM10/11/06
to perl6-l...@perl.org
Hi all,

I posted this to Perl6 users, but I was Warnocked, it was the wrong list, or both. Here's another stab at it.

In doing a bit of work with traits (roles) in Perl 5 (http://perlmonks.org/?node_id=577477), I've realized some edge cases which could be problematic.

First, when a role is applied to a class at runtime, a instance of that class in another scope may specifically *not* want that role. Is there a way of restricting a role to a particular lexical scope short of applying that role to instances instead of classes?

Second, how can I remove roles from classes? I've create some code which adds an "is_selected" method to some classes but when I'm done, I'd like top easily remove that role. How do I do that? Seems closely related to my first question, but it's still a distinct issue, I think.

Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says:

You can also mixin a precomposed set of roles:

$fido does Sentry | Tricks | TailChasing | Scratch;

Should that be the following?

$fido does Sentry & Tricks & TailChasing & Scratch;

Cheers,
Ovid
--
Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/

TSa

unread,
Oct 11, 2006, 7:18:21 AM10/11/06
to perl6-l...@perl.org
HaloO,

Ovid wrote:
> First, when a role is applied to a class at runtime, a instance of
> that class in another scope may specifically *not* want that role.
> Is there a way of restricting a role to a particular lexical scope
> short of applying that role to instances instead of classes?

I think you'll need an intermediate class that you use to apply your
role. Classes are open and that implies the possibility to merge
further roles into them. But this applies for all users of the class.
How this works when there are already instances I don't know.


> Second, how can I remove roles from classes?

Is that a wise thing to do? Roles are not assigned and removed
as a regular operation. What is your use case?


Regards, TSa.
--

TSa

unread,
Oct 11, 2006, 7:03:07 AM10/11/06
to perl6-l...@perl.org
HaloO,

Ovid wrote:
> Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says:
>
> You can also mixin a precomposed set of roles:
>
> $fido does Sentry | Tricks | TailChasing | Scratch;
>
> Should that be the following?
>
> $fido does Sentry & Tricks & TailChasing & Scratch;

If you follow my idea of a type lattice build from roles with | as join
and & as meet operator these two mean something completely different.
The first is the join or union of the roles while the second is their
meet or intersection. The first creates a subtype of the roles the
second a supertype. But the typishness of roles is debated.

Regards, TSa.
--

Paul Seamons

unread,
Oct 11, 2006, 10:49:05 AM10/11/06
to perl6-l...@perl.org
> First, when a role is applied to a class at runtime, a instance of that
> class in another scope may specifically *not* want that role. Is there a
> way of restricting a role to a particular lexical scope short of applying
> that role to instances instead of classes?

Seems like you could use an empty intermediate role to accomplish the same
thing while leaving the shared class alone.

Shared Class A
Mixin Role B

Class C isa A does B
Class D isa A

Shared Class A is unmodified.

Otherwise, I think that any runtime modification of a class should affect all
instances and future instances of that class.

On closer inspection, is it even possible to add a Role to a Class at runtime?
I thought that Class and Role composition outside of compile time resulted in
a new pseudo Class for the subsequent instances of that composition - in
which case the original Class would remain unmodified.

Paul

Ovid

unread,
Oct 11, 2006, 2:21:04 PM10/11/06
to perl6-l...@perl.org
--- TSa <Thomas....@barco.com> wrote:
> > First, when a role is applied to a class at runtime, a instance of
> > that class in another scope may specifically *not* want that role.
> > Is there a way of restricting a role to a particular lexical scope
> > short of applying that role to instances instead of classes?
>
> I think you'll need an intermediate class that you use to apply your
> role. Classes are open and that implies the possibility to merge
> further roles into them. But this applies for all users of the class.
> How this works when there are already instances I don't know.

Ah, that makes sense.



> > Second, how can I remove roles from classes?
>
> Is that a wise thing to do? Roles are not assigned and removed
> as a regular operation. What is your use case?

I don't think I have a clear use case here because the examples that
come to mind all involve adding and then quickly removing the extra
behaviors when I'm done with them. That's going to be fraught with
bugs.

The "intermediate class" solves the problem but it instantly suggests
that we have a new "design pattern" we have to remember. Basically, if
I can't lexically scope the additional behavior a role offers, I
potentially need to remove the role or use the "intermediate class"
pattern.

I suppose one could look at this as "separation of concerns". If I
have an MVC framework, instances of objects in the M, V, or C portions
might want to exhibit different behaviors, depending upon what I'm
doing with them, but I don't necessarily want those behaviors to bleed
over to the other layers of my application. Whether or not this is a
clean way of looking at the problem, I don't know.

Miroslav Silovic

unread,
Oct 12, 2006, 7:35:23 AM10/12/06
to perl6-l...@perl.org
Paul Seamons wrote:
>
> On closer inspection, is it even possible to add a Role to a Class at
> runtime?
>

If it isn't now, I would certainly like to have a hook available through
MOP (which is, to the best of my knowledge, still unspecified).

>
> I thought that Class and Role composition outside of compile time
> resulted in
> a new pseudo Class for the subsequent instances of that composition - in
> which case the original Class would remain unmodified.
>

I believe 'does' and 'but' operators work that way, yep. Additionally,
they're per instance. Offhand I don't even recall any way to create an
uninstantiated class with a role mixed at runtime (would my
$class_foobar = ::Foo but ::Bar do the trick?)

Miro

Jonathan Lang

unread,
Oct 12, 2006, 12:27:53 PM10/12/06
to Miroslav Silovic, perl6-l...@perl.org
Miroslav Silovic wrote:
> Paul Seamons wrote:
> >
> > On closer inspection, is it even possible to add a Role to a Class at
> > runtime?
> >
>
> If it isn't now, I would certainly like to have a hook available through
> MOP (which is, to the best of my knowledge, still unspecified).

To modify a class at runtime, use C<is also>.

> >
> > I thought that Class and Role composition outside of compile time
> > resulted in
> > a new pseudo Class for the subsequent instances of that composition - in
> > which case the original Class would remain unmodified.
> >
>
> I believe 'does' and 'but' operators work that way, yep. Additionally,
> they're per instance. Offhand I don't even recall any way to create an
> uninstantiated class with a role mixed at runtime (would my
> $class_foobar = ::Foo but ::Bar do the trick?)

Probably not; but C<my ::class_foobar := Foo but Bar> might.

--
Jonathan "Dataweaver" Lang

Larry Wall

unread,
Oct 12, 2006, 1:26:13 PM10/12/06
to perl6-l...@perl.org
On Thu, Oct 12, 2006 at 09:27:53AM -0700, Jonathan Lang wrote:
: To modify a class at runtime, use C<is also>.

C<is also> is compile time. You'd have to eval it.

Larry

Aaron Sherman

unread,
Oct 12, 2006, 5:08:58 PM10/12/06
to publiustemp-...@yahoo.com, perl6-l...@perl.org
Ovid wrote:

> The "intermediate class" solves the problem but it instantly suggests
> that we have a new "design pattern" we have to remember. Basically, if
> I can't lexically scope the additional behavior a role offers, I
> potentially need to remove the role or use the "intermediate class"
> pattern.

my Dog $dog .= new;
my $junkyard = $dog but Guard;

You probably don't need to touch the class, but a particular object. You
can lexically scope changes to an object using but and my quite easily.
If you really need a modified class, then I think this would do it, but
I'm not sure if it works:

my $junkyarddog = class is Dog does Guard {};
my ::($junkyarddog) $spot .= new;

Reply all
Reply to author
Forward
0 new messages