I'm doing some work on Class::Trait to fix a bug in its implementation. (A trait is similar to Perl 6 roles. Think of it as a cross between a mixin and an interface -- sort of). A trait can provide methods to whatever class uses that trait. However, to determine which methods it provides, Class::Trait currently examines the symbol table via keys %{"${trait}::"}. That causes a problem if functions or constants are imported from other modules. Those function are considered trait methods and get exported into the class using the trait. This is bad.

My first thought was to simply require traits to have a @PROVIDES array that lists which traits it provides (and I can possibly provide some sugar using attributes). However, traits can be composed of other traits and I'd need to ensure that those traits have their functions reexported into the class using the composed traits. My first thought is to do something like this:

package Trait::Foo; use Class::Trait 'base'; # the following adds their methods to @Trait::Foo::INHERITED_PROVIDES use Class::Trait qw(Trait1 Trait2); our @PROVIDES = qw/method1 method2/; # and in the Class::Trait::Base class: sub methods { my $class = shift; no strict 'refs'; return @{"${class}::PROVIDES"}, @{"${class}::INHERITED_PROVIDES"}; }

That can work and now each trait merely needs to declare the methods in the @PROVIDES array, but I was wondering if there was a cleaner way of going about this. If I stumble across a function in a symbol table, I don't suppose there's any way to know where it came from, is there? (short of using PPI, for example)

I suppose I can grab those trait methods as soon as use Class::Trait 'base'; is called, but this does require that programmer remembers to declare this prior to using any other module which might export something. I hate adding arbitrary restrictions like that, but it seems the simplest way. (Er, no. Those methods won't be defined yet so I'd have to parse the code. Bad idea.)

Cheers,
Ovid

New address of my CGI Course.


In reply to Detecting an imported function by Ovid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.