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

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.

Replies are listed 'Best First'.
Re^5: Detecting an imported function
by dragonchild (Archbishop) on Nov 17, 2005 at 16:56 UTC
    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?

      So, on my wishlist:

      1. Only export methods this the trait promises to provide
      2. Conflict resolution via method renaming
      3. Conflict resolution via denying a method (so another trait can provide it)
      4. Trait requirements must be explicitly met or we fail at compile time
      5. Properly respecting the above traits even when aggregating traits into a new trait

      With the exception of the first item on that list, Class::Trait handles this. Does Perl6::Roles handle these? If so, I'll consider a switch.

      Cheers,
      Ovid

      New address of my CGI Course.

        Perl6::Roles handles #5 correctly. The rest weren't requirements of Tim, so I didn't implement them. Please provide an API for each item and I'll gladly implement them. Of course, it'd be best if the API was as close as possible to what P6 roles will do, but I'll consider any suggestion.

        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?