In defence of OOP
During the last years it became fashionable to rag on object oriented programming and a decade ago I would join the choir. Hack, when I started with Perl I despised the bloat and inefficiency of many corporate smelling *coughjava* systems and preached the light weight and foreward thinking way that real hackers travel. In this miniseries I want to write why I changed my tune [part one], the best way (IMO) to use OOP [part two] and why inheritance (incl. roles and templates) and delegation or not helpful features (in contrast to polymorphism) [part three]. Maybe there will be more about rating Perl OO features and modules.
Objects are a tool to create abstraction layer - to do anything. It's easy to get overwhelmed by possibilities or run with preconceived ideas. And the larger the system, the harder it is to make wise choices. I think this is one reason why a lot of OO code sucks. The second is bad coding styles. It's not getting taught enough how to find the right abstractions and how to ease the use by proper naming. The third reason is the introduction and teaching of contra-productive features like inheritance and even worse, multiple inheritance.
So why even bother? To make my point lets unwind history a little. Because back in the days a similar discussion ensued about subroutines, which are also a tool to hide complexity behind a meaningful names.
register_customer( $paul ) is much nicer to our intuitive mind than GOTO 230. It frees up mental resources and makes programming easier. And yes there are 0.2% of algorithms that can be written clearer with goto's (inside a subroutine). Were talking here about API design.
The main point is that we are sealing a sub as one unit to be called or not. Rather than jumping with GOTO into the middle of a sub you insert an additional IF statement inside the sub, to have the option to skip a few lines. Old school programmers may yell at you for wasting 5 or 20 bytes. But you gained the peace knowing the sub always starts at line one so when you approach line 20 you know the data is checked and sanitized so only errors might happen you did not thought about yet. If you jump to line 20 of the sub with bad data it might be go well for a while and when things go down its hard to find out why. Having a regulated control flow means also have well defined data, which is the next big win using a sub.
And coincidental but not identical with sub : scopes. Create local variables inside a sub to prevent name collisions with other vars with same name and therefore spooky actions at distance. Its a whole class of problems you instantly can stop to worry and it has no down sides, since you don't want to use the local variables anywhere else anyway. (I only miss the feature that functions can't access anything but their args).
To summarize: scopes - good, routine syntax - helpful and already it is as much about the (regulated state of) data than flow control.
Once you get a lot of subs, you prevent name collisions with name spaces (packages), that also give you order so that each sub is in the right place in the hierarchy. But when the namespaces get nested and names becoming longer you start to whish for classes, so you can call the method directly on the object - but were not there yet. Also, attribute data is sanitized once, when coming via a setter into the object and can be used over and over without any second check. So you can pass the object into a sub and data can be used without check, which makes for more efficient code (huh, efficient and oop in same sentence?). This advantage would vanish if you could reach into object internals, when not having no real encapsulation like in vanilla p5 - but still this is not my main two points.
With the ability to capsule data you can guarantee to oblige to contracts, since no-one else touched the data than the little code you have inside your small class. Most importantly - strict abstraction layer walls will let you know if your abstraction layers are appropriate (if there is no need to violate them or if your classes or methods get to big). These are clear signs that code has to be refactored. And if you have too many classes - it is a sign you don't have enough high order classes. OOP can be used in a very functional manner which is often less painful (in larger projects) than being strictly functional and fighting with the harsh rules of monads all the time. But how exactly do that will be content of the next part ....