|Don't ask to ask, just ask|
Re: Re: Objects with Private Variablesby Excalibor (Monk)
|on Jul 08, 2003 at 09:27 UTC||Need Help??|
Indeed. One way to avoid this is to make the methods available for just the attributes we have:
This will make it enough. We make a lexical of the attributes we need, then wrap it inside the constructor (the closure) so it's remembered when it goes out of scope. We also create setters/getters on the flight, a beautiful ability if not abused.
We also make a nifty trick I learned from Master Damian Conway, by making it lexical, the rest of the class methods (salute(), but actually all of them defined outside the constructor) must use the setter/getters (or the interface) defined inside the lexical scope. Effectively, there's no way for salute() to access the state of the object but by asking it through the methods available.
Let's put this to work:
The output from this is, as expected:
The initialization and setters worked OK, and then salute() worked as expected. When we tried to trick the object with another method, by adding to the supposed table of methods, it didn't work, because we explicitely know which attributes we manage (in the normal approach, you can never know). This approach makes lifes easier to maintain (just add a new attribute to the array!) and allows us to be very paranoid about access... and by being a lexical, only the code inside the scope of @attributes can change it, but it never does, and so you cannot trick the object. Of course, there's always a way, you can work on perl guts and add a new attribute to the *attributes table, maybe.
Anyway the example was a nice one, point well taken.