in reply to Re: OO Getters/Setters
in thread OO Getters/Setters

I really have to disagree with your first supposition. There is a world of difference between $obj->{field} and $obj->field(). In fact, the difference is one of the cornerstones of oo.
With the direct access, I have no control over the field. The consumer can store anything it it, squirrel away references to it, change the internal state of my object from a distance using those references, etc.
With the accessor, I have complete control over the field. I can validate changes to the field using any criteria I choose. I can change storage methods. I can manipulate the data internally. I can do anything I need to, without breaking the users code and without the user breaking my code.

UPDATE: It also removes an entire level of error prevention. There is no way to detect mistyped fieldnames. The following code fails silently bacause it is syntactically correct, and without accessors there is no mechanism to detect bad field names.
my $var = $obj->{field}; $var = someManipulation($var); $obj->{feild}=$var;


-pete
"Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."

Replies are listed 'Best First'.
Re: Re: Re: OO Getters/Setters
by hardburn (Abbot) on Dec 31, 2003 at 15:13 UTC

    With the direct access, I have no control over the field.

    In Perl you do, via tied scalars in the internal attributes. I don't think this method is common, but it can be done.

    With the accessor, I have complete control over the field.

    If you're doing something more complex than setting or getting an attribute (no validation, etc.), then it's not a true accessor or mutator.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

      If you're doing something more complex than setting or getting an attribute (no validation, etc.), then it's not a true accessor or mutator
      Since when? I have always understood an accessor to be a method that presents an attribute of the the object to the consumer and a mutator to be a method that allows the user to change an attribute of an object in a controlled way. By your reasoning, the following code should work, and any code in the mutator to prevent it disqualifies the method as a mutator:
      my $year = $obj->birthyear(); $year = "Elmer J. Fudd Millionaire"; $obj->birthyear($year);


      -pete
      "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."

        By your reasoning, the following code should work, and any code in the mutator to prevent it disqualifies the method as a mutator

        That's correct. Accessors/mutators, by definition, provide direct access to the underlieing attributes. Since Perl is a dynamically typed language, that means doing any sort of validation on the data makes it something other than an accessor/mutator. If you're in a statically typed language, then the language does some validation for you, and it would thus still be an accessor/mutator. The important point is that you're not doing validation in your own code.

        So what if it isn't an accessor/mutator? More often than not, that's a good thing. That isn't to say you have a well-designed object, but you're closer to it than if you provide direct access.

        ----
        I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
        -- Schemer

        : () { :|:& };:

        Note: All code is untested, unless otherwise stated

Re: Re: Re: OO Getters/Setters
by flyingmoose (Priest) on Jan 03, 2004 at 15:45 UTC
    While this is true (and valid), there is something to be said about one of the worst abuses of OO, particularly among Java programmers....writing a getter/setter for every method to avoid making variables public. This is misguided.
    private int foo; public int getFoo() { return foo; } public void setFoo(int foo) { this.foo=foo; }

    In this case, the programmer thought that they were preventing access to an internal variable that should have been encapsulated, but they wrote methods that completely bypass that encapsulation. In this case (with no logic restricting input values), they have essentially made the "int foo" public, which is what they were avoiding in the first case. Also, this introduces greater overhead in calling additional functions.

    I would much rather see OO folks think in terms of objects and have their methods have meanings, rather than to see them implement code as merely data structures with optional bounds checking behavior.

    Essentally (and I am speaking in that accursed Java language):

    Here the methods have meaning to the object thing.move(+1,-1); Here we just have a "objectified" data structure and we aren't really OO thing.setX(thing.getX()+1,thing.getY()-1)

    So if you want to be all "Object Oriented", that's fine, but most most programs that declare them to be OO simply are not, they are just restricted data structures that are often 5x more complicated than they need to be. "Functions operating on Data" worked fine for many years and there is nothing wrong with it. For many programs, it's healthy to have a few objects mingling with non-OO constructs, since pure OO can really be detrimental in many cases. It can steamroll out of control (especially if you write a function for most variables!)

    In fact, developing good data structures and programs are really a lost art, as many OO zealots can develop huge OO tree hierachies that obfuscate a lack of good up-front design. Sooner or later, a simple program that could have been written in a 1000 lines is now written in 1000 files!