Slash Boxes
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

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

  (email not shown publicly)
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Tuesday January 31, 2006
07:58 PM

Outside-In objects.

[ #28535 ]

If Abigail's technique of creating objects is "inside-out objects", then standard blessed references would be outside-in objects, yes? And I think they're OK, with a caveat.

They're very easy to use, very easy to clone, but the limitations are annoying. The lack of encapsulation is the biggest problem. However, by "lack of encapsulation" I don't mean "hide it from your users". Things works better when you provide more information, not less. Encapsulation, in this sense means stopping your objects from relying on the internals, even their own. Though I've a nasty habit of doing the following, it's a bad idea:

sub weekly_pay {
  my $self = shift;
  if ($self->{hours_worked} <= 40) {
    return $self->{wage} * $self->{hours_worked};
  else {
    return $self->{wage} * 40
        + ($self->{wage} * 1.5) * ($self->{hours_worked} - 40);

The following is much cleaner:

sub weekly_pay {
  my $self = shift;
  if ($self->hours_worked <= 40) {
    return $self->wage * $self->hours_worked;
  else {
    return $self->wage * 40
        + ($self->wage * 1.5) * ($self->hours_worked - 40);

Why? Well, some argue that it's OK for an object to rely on its own internals and some argue that the first version is slightly faster. However, there are some problems. Though some are well-known, I'll just point to the big one. What if someone wants to override wage()? They might want to look up a standard wage for temp workers, for example. Overriding that method doesn't help if the class is just grabbing the value from the hashref. The weekly_pay() method might return bad results.

The solution to that seems to be to override the weekly_pay() method. However, that means duplicating some logic and if the logic changes, that's a bad thing. Of course, with a typical blessed hashref, you still have to reach inside for the getter/setters, but that's OK. You're limiting your exposure.

Thus, encapsulation is about decoupling your code from your implementation, not about telling your users they can't see the data.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • I agree. A module should always use its own methods over accessing private data whenever possible. This is especially true for subs that clean data on the way in, or when using lvalues.

    A quick example... sub custnum(value) does sanity checking on the value passed in. Now, any code in that same module can save directly to $self->{customnum}, but they miss the sanity checking code.

    I think there is afine line in there. IT all depends on the data being set, and if there are any data manips/check that should
    • For me, it simply removes an extra pair of braces, thereby making the code read a lot more easily. All the rest are side benefits. :-)


  • ...Eating your own dog food.

    See Andy's post from late 2003 []

  • When an hourly rate employee works overtime, it is typical that they get paid time-and-a-half or double time - i.e. (wage * 1.5) or (wage * 2.0).

    What kind of a sweat shop are you running that pays overtime hours at half the normal rate? (It sounds like a programming shop, except that there overtime hours get (wage * 0.0) :-)

  • I don't know where you get the idea that Outside-In is the opposite of Inside-Out, as it is actually the same thing: something where the inside and the outside are swapped.

    The opposite of Inside-Out is Outside-Out, or Inside-In, or just plain and simple: "normal".