in reply to Generally accepted style in Perl objects

That is what I gathered, but I thought I would find out what the general concensus was before moving forward. Laziness is what drove me to ask, I had little enthusiasm for the idea of writing a whole bunch of "addFavoriteColor()" and "removeCondiment()" subroutines. But, in the interest of doing it right, I'll hide away the specifics in subs.

Thanks,

Hot Pastrami
  • Comment on Re: Generally accepted style in Perl objects

Replies are listed 'Best First'.
(Ovid - installing AUTOLOAD subs in symbol table)
by Ovid (Cardinal) on Dec 29, 2000 at 21:40 UTC
    One thing to consider: while you can use AUTOLOAD to create those methods for you, it has a lot of overhead. If those methods are to be called frequently, you can write them by hand *or* use AUTOLOAD and have it install the methods directly to the symbol table. Here's a (simplified) routine from Object-Oriented Perl by Damian Conway:
    sub AUTOLOAD { no strict 'refs'; my ($self, $newval) = @_; # was it a get_... method? if ( $AUTOLOAD =~ /.*::get(_\w+)/ ) { my $attr_name = $1; *{ AUTOLOAD } = sub { return $_[ 0 ]->{ $attr_name } }; return $self->{ $attr_name }; } # was it a set_... method? if ( $AUTOLOAD =~ /.*::set(_\w+)/ ) { my $attr_name = $1; *{ AUTOLOAD } = sub { $_[ 0 ]->{ $attr_name } = $_[ 1 ]; retur +n } }; $self->{ $attr_name } = $newval; return; } # Whups! Bad sub croak "No such method: $AUTOLOAD"; }
    That will auto-create "set" and "get" methods and install them in the symbol table for you. Subsequent calls to those methods will find them and not incur the AUTOLOAD overhead. Needless to say, this method is useful primarily if you have many subs with similar functionality.

    Incidentally, the "simplification" I mentioned was my removal of a hash lookup to verify whether or not one was allowed to read or update the variable in question. You'll want to account for that. I left it out so the code would be clearer.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Re: Generally accepted style in Perl objects
by mirod (Canon) on Dec 29, 2000 at 04:09 UTC

    You can always use AUTOLOAD to generate accessor methods on the fly: grab the name of the method and create (through eval) a method with that name that accesses the field in the object. If one day you want to change the implementation and write the method it will be found and AUTOLOAD won't be called anymore. CGI.pm uses this method, you should have a look at its code.

Re: Re: Generally accepted style in Perl objects
by blueAdept (Beadle) on Dec 29, 2000 at 09:21 UTC
    It sounds like you may want to have multiple methods for your object's user to use, but may be able to get away with doing all the dirty work with only one method which you'd want to keep internal to your object. like:
    $obj->add_condiment('Cheeze');
    Then in your object's package:
    package whatever; ... sub add_condiment { my $obj = shift @_; $obj->set_property("add", "condiment", "cheeze"); } sub add_color { my $obj = shift @_; $obj->set_property("add", "favoriteColor", "blue"); } sub set_property { my $obj = shift @_; my $action_type = $_[0]; my $property_type = $_[1]; my $item = $_[2]; if( $action_type =~ m/add/i && exists $obj->{'properties'}->{"$prope +rty_type"} ) { push @{$obj->{'properties'}->{'$property_type'}}, $item; } elsif( $action_type =~ m/remove/i && exists $obj->{'properties'}->{" +$property_type"} ) { ## loop over the items till you find what you want to ## remove, then remove it } else { die "Something unplanned happened"; }
    Technically the larger method doing the dirty work could be called as a function(maybe more efficient) by explicity passing the object reference as the first arguement(i.e. <code>set_property($obj, "add", "condiment", "cheeze") ) Hope mantaining all those properties doesn't seem like such a daunting task now. :) toodlez.
Re: Re: Generally accepted style in Perl objects
by stephen (Priest) on Dec 29, 2000 at 04:27 UTC
    If the properties are completely unprocessed (i.e. you never rely on knowing what someone's favorite mustard is), you can probably get away with "add_property()", "set_property()", "get_property()", "get_all_properties()", and "delete_property()" routines. That'll keep you away from making assumptions about the internals that may later change, but is flexible enough so that you don't need to keep changing the class interface (which is only slightly better than having no interface at all.)

      I like the way you explained breaking out standard functions, from core functions. It's something I've always done, but have found myself hard pressed to enunciate as to why I do it. It has always stumbled out of my mouth as, "Cuz I don't want to mess the other files up".

      I do have a small point of contention with a portion of your conclusion though. You said,

      ...changing the class interface (which is only slightly better than having no interface at all.)

      Speaking from my position as a struggling Perl person that's learning both the base perl code and the many abstractions1 of perl as 00. I can suck the power of a 2 processor SPARC 450 because of the horrendous programing in my applications core modules. For this reason I contend that,
      Changing the class interface, is worse than no interface at all.

      coreolyn Duct tape devotee.
      -- That's OO perl, NOT uh-oh perl !-)


      1 From my slighlty crazed point of view, OO Perl takes Perl from being 'duct_tape' to 'silly putty on acid'.
        Preachin' to the choir. :)

        stephen