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
| [reply] [d/l] |
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.
Pedantry such as this seems useless to me. If the object's interface says the only way to access an attribute is by using method foo, then for all intents and purposes, foo is an accessor. Believing anything else pierces the veil of encapsulation and defeats one of the main purposes of object orientation.
Ah, but now I'm into the fray... Quick! What's a "block structured language" and why is C not one of them? For bonus points, how does the fact that C is not block structured affect your ability to write useful applications?
| [reply] [d/l] [select] |
Pedantry such as this seems useless to me.
No, I think the distinction is important. If your interface provides direct access to the attribute, it's not encapsulating anything, and thus breaking the foundations of OO design. That doesn't automatically make it bad, but it often is.
Quick! What's a "block structured language" and why is C not one of them?
This isn't something I've encountered before. But with a little help from Google . . .
Block structured languages allow you to have functions nested inside other functions. C/C++ doesn't allow this, which means all those great tricks with closures in Perl and similar languages can't be done.
---- 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
| [reply] [d/l] |
I'm not entirely sure where you learned object orientation, but it seems you need a new lesson in it. Object Orientation is a methodology a way of writing a program. Which means that its principles are language agnostic. Perl in my opinion is one of the worst languages to write oop programs in because it breeds hideous techniques such as yours. Attribute encapsulation is a cornerstone of OOP. The simple fact of the matter, is that accessors/mutators are methods to retrieve bits of object data or set bits of object data. What they do and how they do it is irrelevant. From my point of view, there are very few times when you would want to expose member variables (a.k.a attributes) to the public.
Indeed, I've never encountered a situation which required this. I find the maintainability of encapsulation a Godsend.
This allows me to trivially change the data structure without concern. You spoke of tied scalars etc, but by that argument you invalidated your previous argument over performance. You will never convince me that using a tied scalar is more efficient, easier to use, and easier to maintain than accessor/mutators. I'm sure you are a fine procedural programmer, but I would recommend you study up on your OOP before you go giving advice. May I suggest Object Oriented Perl.
On a further note, there are times when pedantry is needed, this was not one of them. When misused pedantry is counter-productive and infuriating.
It's like the force, use it well.
| [reply] |
From my point of view, there are very few times when you would want to expose member variables (a.k.a attributes) to the public
But if you're blindly adding accessors/mutators, you might has well have made them public. This isn't a blanket ban on accessors/mutators, but a note that people should be more careful about adding them.
You spoke of tied scalars etc, but by that argument you invalidated your previous argument over performance.
Perl's objects are already slow. In any case, my tied scalar example was nothing more than an example. It demonstrates that $obj->attr and $obj->{attr} are only different in syntax, since you could use a tied scalar to preform exactly the same operations that an accessor/mutator could do. I don't recommend either approach, though, but rather eliminating accessors/mutators all together whenever possible.
Which of these is a better object for a vending machine?
sub money . . . # Accessor/mutator to how much money is in the machine
sub get_drink . . . # Spit a drink out
Or this, which avoids mutators entirely:
sub insert_coin . . . # Insert a coin (quarter, dime, whatever) into m
+achine
sub money . . . # Accessor to how much money is in the machine
sub get_drink . . . # Spit a drink out
The second one will restrict what kind of money you can put it and adds that coin's value to the internal attribute. It is not a mutator, because it doesn't provide direct access to that attribute. money is an accesor in either case, but I don't consider it a problem, since the user needs some way of figuring out how much money is in the machine so they can insert more if need be. get_drink has the same implementation in either case, and would only spit a drink out if there was enough money in the machine.
The second interface is more complex, but it's a better design because we've abstracted the operation of inserting coins into the machine. We can subclass it to take other kinds of coins or to take cash (though insert_coin wouldn't be the best name in that case). The point is that you've restricted what kind of data can go in, which the first class would have a much harder time doing.
---- 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
| [reply] [d/l] [select] |