The key to all things OO is encapsulation. Basically you publish an interface which people then use. If you start changing the behaviour of the interface then you are going to cause problems. The thing to remember is that accessor methods are as much a part of the encapsulation as constructors or other more conventional methods and should be treated with the same respect. The problem that has been highlighted is that the lazy implementation of get/set functions as a thin layer over the top of the internal representation is brittle and may cause a maintenance headache.
In your example you have a method (sub) called get_array. You have published an interface that says 'Whenever you invoke this method you will get an array to work with'. This is in effect a contract between you, the designer of the class and whoever uses your class. When the internal representation of the data changes to a hash, the get_array method will end up doing more work since it now needs to construct an array to pass back to the caller. Thus maintaining the contract and not causing problems.