in reply to Perl OO and accessors

Presumably you'd also want

get_radius() get_area()

but then you could use the magic of lvalue subs and tie to let you replace these 4 functions with 2 accessors (it's much less messy in ruby or python)

radius area

so you could do

$c->area = $c->area / 2; $c->radius = $c->radius * 2;

Neither of these expose an attribute, despite how it looks. Whether the inplementation actually stores the radius or the area it doesn't matter, neither of these are exposed here, because all interaction is mediated by the methods.

The only thing that is "evil" is unmediated (actually unmediatable) exposure of an attribute. In Java, where this notion of "evil" originates, there is no such thing as mediated exposure of an attribute. The evil in Java is that once an attribute is exposed, it cannot be unexposed and so the interface dictates the implementation forever more.

In languages like Perl, Python, Ruby, Object Pascal and many others it is possible to create something that looks like an attribute but does not force anything on the implementation and so there is no evil. In some of these you can even expose an unmediated attribute and later turn it into a mediated attibute without changing the interface (hence the "unmediatable" above).

So in some languages exposure is evil because the exposure is real and irrevocable but other languages allow you apparently expose or to revocably expose an attribute without forcing anything on the implementation.

Replies are listed 'Best First'.
Re^2: Perl OO and accessors
by sauoq (Abbot) on Nov 29, 2005 at 04:07 UTC
    but then you could use the magic of lvalue subs and tie to let you replace these 4 functions with 2 accessors

    Using lvalue subs for accessors isn't generally a good idea. For instance, what would you do with $c->area = -42? And, how do you go back and change the interface later to avoid lvalue subs?

    -sauoq
    "My two cents aren't worth a dime.";
    
      . . . what would you do with $c->area = -42?

      use Math::Complex;

      ;-)

      After Compline,
      Zaxo

      what would you do with $c->area = -42?

      What you do with $c->set_area( -42 )?

      how do you go back and change the interface later to avoid lvalue subs?

      How do you go back and change the interface later to avoid set_foo methods?

      Makeshifts last the longest.

        What you do with $c->set_area( -42 )?

        Maybe I'm missing something. Say that I implemented set_area as

        sub set_area { my $self = shift; my $area = shift; die "Area must be non-negative." unless $area >= 0; # ... }
        How do you do the same with an lvalue sub?

        How do you go back and change the interface later to avoid set_foo methods?

        You don't. But, that's okay because you never have a need to.

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

      That's why I said lvalue subs and tie.

      You don't think I'd write all the spiel about irrevocable exposure and then go and suggest a method that is irrevocable.

      The technique involves returning a tied lvalue which then calls a setter method with the new value. All this can be hidden behind a use statement. See Class::Accessor::Lvalue for an example.