Outside-In objects.

Ovid on 2006-02-01T00:58:18

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.


Here Here!

jk2addict on 2006-02-01T03:18:05

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 happen beefore setting the data.

Re:Here Here!

Dom2 on 2006-02-01T08:28:18

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. :-)

-Dom

AKA...

LTjake on 2006-02-01T12:28:59

...Eating your own dog food.

See Andy's post from late 2003

cheap overtime

jmm on 2006-02-01T14:35:44

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) :-)

Re:cheap overtime

Ovid on 2006-02-01T16:21:46

Oops! Fixed, thanks.

Outside-Out

bart on 2006-02-01T21:41:17

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