in reply to Re^7: Assignable Subroutines
in thread Assignable Subroutines

Your app may not have needed publicly accessible mutators but what happens in another app when I want to set the Salary property of an Employee object? What is the alternative to a publicly accessible mutator?

Replies are listed 'Best First'.
Re^9: Assignable Subroutines
by hardburn (Abbot) on Jan 26, 2005 at 14:14 UTC

    Why isn't your salary in the database? Why aren't you changing it there?

    If your object is simply an access layer above the database (Class::DBI or something along those lines), then the mutator is no longer trivial.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      How do you change it there? What is the mechanism by which you are going in and fiddling those bits? Presumably, it's some sort of access layer. Presumably, the access layer is made up of objects. And, presumably, you need a mutator.

      Once you want a mutator, you want the syntactic sugar that goes with assignable subroutines.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        Which is why I mentioned Class::DBI and similar layers. Once your method is running SQL statements (as opposed to simply changing an internal variable), it's no longer a trivial mutator. Complex mutators are a different beast :)

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      Maybe it is in the DB but I'm not changing it in the database because the part of my program that wants to mutate the Employee doesn't (and shouldn't) need to know about databases. Also, storing it in a DB does not always mean that the mutator handles updating in the DB. If persistence is handled by a framework outside the object then the mutator remains trivial and storage is handled outside of your classes.

      Basically it comes down to the fact that many objects have chunks of them that behave exactly like a record/struct in that they are nothing more than passive fields that get twiddled by outsiders. These plain old fields should still not be part of your public interface because if they need to be something more than just plain old fields in the future you're shafted (unless you're in a language that makes it possible for an object to intercept direct twiddling of it's fields and do fancy stuff - Python's properties for example).

      If you don't provide mutators, even for trivial fields, then you are just storing up pain for the future.

        If you don't provide mutators, even for trivial fields, then you are just storing up pain for the future.

        No, you fix your design so you don't need them in the first place.

        In this case, I would make an "effect" object (I'm sure there is a Pattern for this). An effect stores values that can mutate other values when applied to another object.

        my $employee = Employee->new( salary => 50_000 ); my $effect = Effect->new; $effect->set( salary => 1.02, '*' ); # A 2% raise $effect->set( frobnitz => 1.5, '+' ); # The frobnitz is up $employee->apply_effect( $effect );

        The key here is you don't need to know for certain that a given field is implememented in Employee. The apply_effect method ignores any fields it doesn't recognize (like frobnitz). I'll give you that it is more lines of code than:

        $employee->salary( $employee->salary * 1.02 );

        But it is also a superior form of encapsulation.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

        Ahh, I was right about there being a Pattern for this. It's basically a Visitor Pattern.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.