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

use Perl Log In

Log In

[ Create a new account ]

TeeJay (2309)

TeeJay
  (email not shown publicly)
http://www.aarontrevena.co.uk/

Working in Truro
Graduate with BSc (Hons) in Computer Systems and Networks
pm : london.pm, bath.pm, devoncornwall.pm
lug : Devon & Cornwall LUG
CPAN : TEEJAY [cpan.org]
irc : TeeJay
skype : hashbangperl
livejournal : hashbangperl [livejournal.com]
flickr :hashbangperl [flickr.com]

Journal of TeeJay (2309)

Tuesday November 21, 2006
02:56 PM

Further adventures with Class::Trait and CDBI

[ #31678 ]

I've been doing some more work with the Class::Trait traits I've written, for a client in the aviation industry, to enable various hairy searches on cdbi classes, and found that I frequently wanted to add extra temporary fields to the classes that are populated by the searches.

The result is this little hack..

=head2 extra_fields

Returns an array of any additional attributes this trait can populate

__PACKAGE__->columns( TEMP => qw/foo bar/,__PACKAGE__->extra_fields );

=cut

sub extra_fields {
    my $self = shift;
    my @fields = ();
    foreach my $trait ( $self->does ) {
        (my $traitname = $trait) =~ s/^(\w+\:\:)+(.*)$/$2/;
        my $extra_field_subname = lc("_extra_fields_$traitname");
        if ($trait->can($extra_field_subname)) {
            push (@fields, $trait->$extra_field_subname);
        } else {
            warn "trait $trait doesn't have extra fields";
        }
    }
    return @fields;
} ..which goes in a trait used by the individual search traits (it's there to provide various shared functionality), which are in turn used by the CDBI classes. ..then I add the sub below in the MyApp::Traits::Foo trait

sub _extra_fields_foo { return 'distance'; }

Now I can add a column named 'distance' to any query in that trait, and the it'll populate that attribute in all the objects in the result.

This is because Class::DBI's sth_to_objects class method will map all columns in the results of a query to attributes in the object, and using the temporary fields means it won't try to save them if you want to modify an object.

What would be really neat would be if Class::Trait allowed you to set method attributes to make methods private or friends, C++ style - I'll email Ovid at some point about it.

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.
  • I'm rather interested in that. It's a fascinating approach.

    As for private and protected methods, private methods can be supported merely by using sub assigned to a variable:

    my $private = sub {
      my $self = shift;
      # do stuff
      return $result;
    };

    sub foo {
      my $self  = shift;
      my $stuff = $self->$private(@_);
      # do more stuff
    }

    That has the advantage of working right now without requiring any code in Class::Trait to change. As for protected or trusted methods, I'm not

    • Thanks :)

      I was thinking of something like..

      sub _internal_foo : private { .. }

      or

      sub _internal_shared_foo : protected { .. }

      using sub attributes

      The subs hack will work within a trait, but the code I posted is in a trait used by other traits, so it needs to access what is in them, at the moment anybody can access them, which doesn't worry me too much, I only want to avoid the namespace pollution that would come if I added a ton of extra methods shared between this group of traits :)

      It's fun to mix idioms from
      --

      @JAPH = qw(Hacker Perl Another Just);
      print reverse @JAPH;
      • Actually, I've already received a patch for that syntax, but in asking around, I received feedback from folks suggesting that they weren't too keen on using attributes. The only reference I can find to that is here.

        But are protected methods that useful here? Protected methods can be inherited, but part of the impetus behind traits is to lesson folks dependence on broken inheritance schemes. Still, I can see how some folks might like them.

        As for private methods your trait can provide to classes, I woul

        • I'd be interested in that patch, maybe in order to put together a subclass that just adds it onto Class::Trait.. although I suspect that would be nontrivial..

          Presumably the patch is attached to a wishlist item in rt?

          'Fraid I'm still stuck on dial up since moving house and so can't really do much useful apart from throw peanuts from this here gallery until next week.
          --

          @JAPH = qw(Hacker Perl Another Just);
          print reverse @JAPH;