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

I don't understand what you mean by "higher up".
I mean the code to handle this is lifted outside the class and into the caller.
It's in the caller in your code too, it's just all stuffed into an effect object which is created and applied by the caller and I still haven't seen an example of why that might cause a problem.
I, for one, like the addition of small, domain specific languages. Your choice is to either learn an API or learn a (small) language. Choosing one or the other tends to force you twards different design decisions, but the cost of learning is not so different.
Yes they're great but I have 2 problems with your. If you want to continue use it fine but I really recommend looking at Tangram, the techniques in there would allow you to replace
my $effect = Effect->new( [ salary => 1.02, '*' ], [ frobnitz => 1.5, '+' ], ); $_->apply_effect( $effect ) for @employees;
with
my $effect = Effect->new; $effect->salary *= 1.02; $effect->frobnitz += 1.5; $_->apply_effect( $effect ) for @employees;
which may not look so different but because it's actual Perl it requires no learning at all. It also would allow stuff like
$effect->salary = $effect->frobnitz + 1.5;
Encapsulation is hiding data and behavior. Applying trvial mutators exposes data. It's therefore bad encapsulation. QED.

That's exactly the circular logic I was talking about. Your using your own definition of encapsulation to to justify itself. You've basically said "it's not my kind of encapsulation therefore it's bad encapsulation".

For me, encapsulation does not mean hiding all data it just means hiding particular pieces of data from particular parts of the program. In many situations, some data really does need to be exposed but by exposing the data through methods you are not breaking encapsulation because the actual internal data is still guarded from direct manipulation.

You keep talking about trivial mutators. Are non-trivial ones OK? If so what should I do if I change my implementation so that a non-trivial mutator is now trivial?

Replies are listed 'Best First'.
Re^19: Assignable Subroutines
by hardburn (Abbot) on Jan 27, 2005 at 22:30 UTC

    It's in the caller in your code too, it's just all stuffed into an effect object . . .

    No, my code just provided the data for the Effect object to do its job. Your code put actual code (subroutine refs) to do the job. I want all of this information hidden away by the object.

    It's domain is already completely covered by Perl

    That gets down to a Turing completeness argument. Sure it's already covered. But I want to make a better one.

    Your language has to be typed in as a structure that represents a parsed syntax tree which is not so convient

    In your opinion. I rather like it.

    The example replacement ([ salary => 1.02, '*' ] with $effect->salary *= 1.02), is a matter of syntax. It's not a fundamentally different design.

    Your using your own definition of encapsulation to to justify itself.

    Hardly mine alone. From the OODBM Manifesto:

    We believe that proper encapsulation is obtained when only the operations are visible and the data and the implementation of the operations are hidden in the objects.

    This is the standard definition (with some variation) of encapsulation I've allways heard. OO provides one way of doing encapsulation (though it hardly has a monopoly on it).

    It's hardly circular. Encapsulation hides, trivial mutators expose. These are mutually exclusive concepts.

    You keep talking about trivial mutators. Are non-trivial ones OK? If so what should I do if I change my implementation so that a non-trivial mutator is now trivial?

    Any method that modifies the internal state of the object is a mutator. A trivial mutator passes the input to the method directly into the internal state. Doing verification on the value first is an improvement, but can often be replaced with a more rigid design (like giveRaise() and givePromotion()).

    "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.

      No, my code just provided the data for the Effect object to do its job. Your code put actual code (subroutine refs) to do the job. I want all of this information hidden away by the object.
      Hidden from who? There's no point in hiding it from the caller as the caller is the one that specified what should be done. There's no point hiding it from the object as it needs to know what it's being asked to do.
      The example replacement ([ salary => 1.02, '*' ] with $effect->salary *= 1.02), is a matter of syntax. It's not a fundamentally different design.
      One fundamental difference is that as it stands, yours doesn't appear to handle complex expressions and if you were to extend it so it does you'll probably end up with lisp (because lisp is basically written as a parsed syntax tree) but without all the other great stuff that lisp gives you.

      A quick google search for encapsulation brings up various conflicting definitions including some pages that say that it's not about information hiding at all. As far as I'm converned a trivial mutator exposes nothing. The justification for this is that the thing using the object doesn't know whether it's a trivial mutator or not, all it know is that here's this thing which seems to behave like a storage location for data.

      What do you mean by exposed? I mean that some part of the object can be twiddled outside the control of the object itself. This deifinitely is a bad idea but it's not what's happening in a trivial mutator because the object is still in control.

      Do you take X is exposed to mean that X can is influenced by or visible to outside things but remains under the control of the opject? If you do then pretty much everything in the object is exposed in some way (anything in the object which is not at all influenced or visible by other parts of the system would seem to be irrelevant).

      You seem to be arguing that an object which has one or more things that seem to behave as storage locations for data as part of it's public interface is fundamentally broken. So you're disallowing the concept of a variable as part of an objects interface. I still haven't seen an example of the bad tings that happen when objects have variables in their public interfaces.

      Forgetting about the salary example (because it allows for setting a new value relative to the old value), what about a person with a hand. Why not allow

      $person->HandItem = $thing; print 'he's holding a ".$person->HandItem->name."\n";
      a variable is a perfectly natural interface for this. Any other flexible interface will effectively be an accessor and a mutator just with different names.