in reply to Class attribute get/set approach flaws?

Using a single accessor for setting/getting all your attributes is a bad idea because you can't easily do any validation or implement behavior specific to a particular attribute.

Say, for example, that you have an Employee class and you want to double check that an employee's salary isn't being set to a negative value or you want to update his benefits eligibility when his full_time attribute is set to true.

-sauoq
"My two cents aren't worth a dime.";
  • Comment on Re: Class attribute get/set approach flaws?

Replies are listed 'Best First'.
Re^2: Class attribute get/set approach flaws?
by Ovid (Cardinal) on Nov 28, 2005 at 23:26 UTC

    Not necessarily true. It can actually make code easier to work with.

    my %validation_for = ( foo => qr/^\d+$/, # foo must be an integer bar => \&validate, }: sub attr { my ( $self, $attr ) = splice @_, 0, 2; croak "No such attribute $attr" unless exists $validation_for{$attr} +; return $self->{$attr} unless @_; # set the value my $validation = $validation_for{$attr}; my $new_val = shift; if ('Regexp' eq ref $validation) { croak "$new_val doesn't match $validation" if $new_val !~ $validation; } else { $self->$validation($new_val); # we'll assume it throws an error } $self->{$attr} = $new_val; return $self; }

    With that quick hack, adding a new attribute is as simple as adding a new key/value pair to the validation lookup.

    You can then use a single method for getter/setters for everything and still have validation. Whether or not that's appropriate for your needs depends on your requirements. Also, "extra" behavior can easily be added to the validation subroutine, though at that point you'd probably want to rename the hash.

    Cheers,
    Ovid

    New address of my CGI Course.

      With that quick hack, adding a new attribute is as simple as adding a new key/value pair to the validation lookup.

      Well, that glosses over the fact that adding the key/value pair might not be easy depending on the validation and/or behavior you need for a given attribute... You might need to write a new validation function, for instance. And, you might want to change the names of things a bit if, for instance, you want functions that don't just perform validation but, say, set other values. (Change the radius and update the area, to use an example that's been used frequently today.)

      But, okay. Yeah. Sure. You can do things like that. I've even done it, though not quite like that.

      It might even buy you something in the common cases... I'm not sure how much though and I've come to think that just writing a separate method is easy enough and usually neater. So, that's what I usually do these days. (I do prefer accessors that both set and get though.)

      -sauoq
      "My two cents aren't worth a dime.";
      

        How do you avoid problems with passing in zero length lists when you're setting a value? How do you distinguish the setting form of $obj->foo( new_value() ) from $obj->foo() if new_value() might return an empty list?