Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Hi, could you contrast Class::Trait to Class::Role? Thanx!
    • Note that in the following that I do not use the word "role" even though that's the Perl 6 term. This is deliberate to make it clear I'm only talking about Perl 5 traits. Even when I discuss Class::Role I'll call it a trait. Yes, I know that's awkward :)

      Well, first and foremost, Class::Trait [cpan.org] is the only Perl module to have a substantially complete implementation of traits as described in the classic "traits paper [unibe.ch]" that introduced most programmers to traits.

      As for Class::Role, it appears to have the s

      • The Perl6::Roles module supports runtime role composition:

              Name::Of::Role->apply( $some_object_of_unknown_class );

        Can (does/will) Class::Traits support that?
        • It's possible that it will. For the time being, I'm doing some deep internals work with it to make sure that I have everything nailed down. After I feel truly comfortable with its current state I'll start expanding it.

          • I need runtime role composition for DBI v2 prototyping which will be layered over my JDBC module. JDBC can return handles to funky internal Java classes that vary with the driver being used.
            • Currently there is a workaround:

              use Class::Trait;
              Class::Trait->import('TTrait1', 'TTrait2');
              Class::Trait->initialize;

              That will properly use those traits, report conflicts, etc. However, it only works once. If both of those traits have identically named methods, the initialize() will fail. The following will not work:

              use Class::Trait 'TTrait1';
              Class::Trait->import('TTrait2');
              Class::Trait->initialize;

              This is because by the time the second trait is used, the meta information for the firs

              • While that would be runtime it's not 'dynamic' (for want of a better word). I looks like I'd have to do something like this:

                        eval sprintf "package %s; Class::Trait->apply(%s);",
                                ref $some_object_of_unknown_class, $trait_class;

                whereas I'd like to be able to do:

                            $trait_class->apply( $some_object_of_unknown_class );

                (which would rebless $some_object_of_unknown_class into a new clas
                • whereas I'd like to be able to do:
                  $trait_class->apply( $some_object_of_unknown_class );
                  (which would rebless $some_object_of_unknown_class into a new class) Both $trait_class and $some_object_of_unknown_class are unrelated to the current package.

                  This is where I'm not sure I'm following you. It sounds like what you want is prototyped OO whereby one can add new methods to an instance and not just to the class itself, is that correct? However, I'm not sure that your syntax is good. How would that chain? If I start from the instance, it seems clear. So assuming that $fido is a Dog who inherits from Mammal:

                  $fido->apply('Sentry')
                       ->apply('Tricks')
                       ->apply('TailChasing')
                       ->apply('Scratch');

                  (Of course, those could all be done in separate statements for those who don't like chaining).

                  And then that would actually get represented as this?

                  +--------+
                  | Mammal |
                  +--------+
                      |
                      V
                  +--------+
                  |  Dog   |
                  +--------+
                      |
                      V
                  +--------+
                  |  Anon  | (Role:  Sentry)
                  +--------+
                      |
                      V
                  +--------+
                  |  Anon  | (Role:  Tricks)
                  +--------+
                      |
                      V
                  +--------+
                  |  Anon  | (Role: TailChasing)
                  +--------+
                      |
                      V
                  +--------+
                  |  Anon  | (Role:  Scratch)
                  +--------+

                  If that's correct, I can make this work. My big concern, though, is having a programmer not realize that TailChasing has a chase() and thereby silently and unknowingly overriding the chase() method in Sentry or Tricks. One could argue that we have this problem when we write a subclass, but we're far more likely to know what the superclass is providing. There's no messing with inheritance at runtime involved. Of course, if this is just prototyped OO, then it makes sense why this is useful, but I'm still concerned, though now that I stop to think about this, just overriding the methods this way is easier than what I've been doing :)

                  Or maybe I'm just paranoid and should trust Larry and the programmers who will use this?

                  Oh, and you're quite welcome (re: your later thanks). We've been happily using traits at Kineticode and have been pleased with the problems they have solved.

                  And FYI: it's easy to add code on use.perl. Just use the <ecode>$code</ecode> tags.