in reply to Re: Detecting an imported function
in thread Detecting an imported function

No, I haven't. Class::Trait is appealing because I am intimately familiar with it and it's a very complete trait implementation including conflict resolution, proper trait composition, enforcement of requirements, method aliasing, reflection, etc. In short, it has everything we need.

Just glancing at your code suggests you might have the same problem that Class::Trait has:

push @methods, map { [ $r, $_ ] } grep { *{"${r}::${_}"}{CODE} } keys %{"${r}::"};

Where do those methods come from? Is there any chance a role might import a function (even as a constant) and have it exported?

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re^3: Detecting an imported function
by dragonchild (Archbishop) on Nov 17, 2005 at 14:13 UTC
    Where do those methods come from?

    From the role's package. The current specification, as I understand it, is that anything a role can do, the class doing the role can do.

    Is there any chance a role might import a function (even as a constant) and have it exported?

    If Role->can('foo'), then Class->does('Role') implies Class->can('foo') for all foo in Role. If this isn't the spec, then I can provide a mechanism in Perl6::Roles that will account for that. Let say you define a "@ROLE_METH" or somesuch. But, the current P6 spec, as I understand it, says that the class will get everything.

    There is some discussion on p6l about whether or not the role will be able to reserve methods that are labelled private/protected/other, but, AFAIK, @Larry hasn't made a decision one way or the other.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      For Perl 6, this is not unreasonable as it's rather easy to disambiguate methods and subroutines. That's not so easy in Perl 5. Instead, consider the example in my root node. I have traits which import functions such as "encode_entities". That's not a method and shouln't be exported by the role. Further, having those things accidentally exported is an encapsulation violation. My classes using roles should not have to worry about what tools those roles use to accomplish their tasks.

      However, that's not the only problem I have here. Right now it's cluttering my namespace but having avoided a bug is only a matter of chance. For example, we have a base class called "Mammal" which provides an "eat" method. It's subclassed by "human" of which we have an instance which "does girlfriend":

      +--------+ | Mammal | (provides "&eat") +--------+ | V +--------+ | Human | (does "girlfriend") +--------+

      Now imagine that the girlfriend trait imports a function to read files and that function is called "eat". If that's exported to human, there's no conflict because the human doesn't implement "eat" directly. However, we've now silently overridden the inherited "eat" method. The code breaks, there's no hint that it's going to. Everything's bad.

      Needless to say, blindly exporting every function causes problems worse than my skills at analogy.

      Cheers,
      Ovid

      New address of my CGI Course.

        When I wrote Perl6::Roles, stvn and I talked through this issue, along with chromatic, Luke, and Tim. The P6 spec says a few things:
        • If a class provides a method, then the corresponding method in the role will be ignored.
        • If an instance does a role on its own, then the role's methods will silently override the methods that the class would provide.

        More importantly, it currently says nothing on whether a role exposes an interface or if it is, itself, the interface. Please bring that up on P6l if that's a problem for you. Right now, P6 roles export EVERTHING, including methods, subs, and the like.

        I briefly thought about providing an optional mechanism by which you can specify in the role what it actually exports. I didn't implement it because that wasn't one of Tim's requirements and I was writing this for him to use in DBIv2. However, if that is one of your requirements, I can easily add it in less than 20 minutes. Please specify if you want to use an array a la Exporter or if you want to use attributes.


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?