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.
  • Hmmm, I've been caught out by using accessors like that before. This is a more general code issue, and it's probably fine for your small code, but what happens if you want to store undef in your accessor?

    This is the reason I am leaning more and more towards Class::Accessor and similiar. I note that you'd have to override set() to return $self that way, however.

    -Dom
    • > what happens if you want to store undef

      I usually write something like

      sub foo {
          my $self = shift;
          return   @_  ? $self->{foo}=$_[0]  : $self->{foo};
      }

      which gives you the ability to set something to undef but doesn't let you chain method calls. If you wanted to chain method calls, you could instead write it this way

      sub foo {
          my $self = shift;
          if (@_) {
              $self->{foo} = shift;
           

      • Put these two subroutines somewhere
        sub non_chaining_accessor {
            my $name = (caller 1)[3];
            $name = substr $name, rindex($name,':')+1;
            $#_  ? $_[0]->{$name}=$_[1]  : $_[0]->{$name}
        }
        sub chaining_accessor {
            my $name = (caller 1)[3];
            $name = substr $name, rindex($name,':')+1;
            if ($#_) {
                $_[0]->{$name} = $_[1];
                return $_[0];
            } else {
                return $_[0]->{$name};
            }
        }
        and then when you want accessors of either type, just do this:
        sub foo { &non_chaining_accessor }
        sub bar {     &chaining_accessor }
        sub baz { &non_chaining_accessor }
        sub bop {     &chaining_accessor }
        and your subs will be accessors for like-named hash keys in a hash-ref-based objet. They'll be slower though (extra subroutine call and three extra function calls per invocation). I suppose you could cache the sub name to hash key lookups to gain a bit of speed in future calls, if that's worth the bother: one function call and a hash lookup instead of three function calls.

        Well, it looks like I'm on the way to re-inventing Class::Accessors now. I just looked at that module, and it seems to do the same sort of thing, but much nicer. It goes another step and lets you just specify the names of the accessors, and it creates the subs and stuffs them in your namespace for you. Since it knows the names of the subs when it creates them, it can avoid that repeated callerIt's also much more configurable.

        At least it was a fun excersize :)

        -matt