Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Perl OOP

by tobyink (Abbot)
on Jul 05, 2017 at 00:33 UTC ( #1194181=note: print w/replies, xml ) Need Help??


in reply to Perl OOP

1. No, because that's a terrible idea. If I've created a class, why shouldn't you be able to inherit from it?

2. Perl objects are (by default) equal when they refer to the same memory address. It makes sense to override this if you have a more useful definition of equality.

3. No, Perl is weakly typed so has no need for anything equivalent to generics. There's little point in creating a List<T> template if lists accept all data types by default.

Replies are listed 'Best First'.
Re^2: Perl OOP
by Arunbear (Prior) on Jul 05, 2017 at 12:40 UTC
    1. No, because that's a terrible idea. If I've created a class, why shouldn't you be able to inherit from it?
    Because it may not be safe to do so, e.g. from Method Privacy in Perl
    Recently I was writing a subclass of somebody else's class and noticed it suddenly started behaving strangely. After an embarrassing amount of time spent debugging I discovered that one of my underscore methods happened to have the same name as one of the superclass' underscore methods (actually two levels up inheritance), so was getting called by the superclass when I hadn't expected it to be.
    Whereas a construct for disallowing inheritance (on a per class basis) would make it clear to a would be subclasser that the class wasn't designed for inheritance.

    But the OP was asking about how (as an author) they can stop their classes from being subclassed. I think this is totally legitimate from a design point of view given all the design warts of inheritance:

    • introduces tight coupling
    • breaks encapsulation
    • increases cognitive load

      But the OP was asking about how (as an author) they can stop their classes from being subclassed. I think this is totally legitimate from a design point of view

      I think it's as legitimate as asking how I, as a car manufacturer, can stop the people who buy my cars from hanging fuzzy dice from the rear-view mirror. Or how I can stop them from keeping their muddy boots on the back seat.

      It's none of my damn business. If I don't want them doing that, I shouldn't sell the car. If I really need the sale, but still don't want them doing it, I can document that it voids the warranty for their expensive leather seats.

        You're confusing the regular use of an object (which no one is arguing against) with modular design of an object (to use inheritance or not).

        The analogy you gave would be relevant to this discussion if it had any semblance to design by inheritance, but it doesn't.

        But staying in the realm of car manufacture, we build cars by composing them out of components.

        Let's say you want to build (using 'inheritance') a new SmartLandRover that has additional sensors to detect when the driver is drunk, but 'inherits' other functionality from a base model Land Rover.

        SmartLandRover doesn't have a battery, so it must have wires connecting it to BaseLandRover so it can get power.

        SmartLandRover also doesn't have an engine, so it must have a shaft connecting it to the drive shaft of BaseLandRover so it can get movement.

        This may seem ridiculous, but we do something quite similar when we use inheritance.

        No one designs or builds cars like that, and with good reason.

Re^2: Perl OOP
by QueenSvetlana (Novice) on Jul 05, 2017 at 00:45 UTC
    Thanks for the reply! In the case of the #1, when creating immutable objects, it's good practice to prohibit inheritance.
      AFIK, there is no such thing as an "immutable object" (an object where the parameters cannot be modified) in Perl. Perhaps there is such a thing in Java or C#. I don't think such a thing exists in C++. Perl is not Java, C# or C++. I guess if you have an object with 'name' as a property when that object was created, just don't expose set_name() in the public interface? If there is no function to change something, and you "play by the rules", then you can't change it. However there are ways in Perl to circumvent any rule and wind up with obscure code that changes a parameter that is not part of the public interface. I think that is also true in C++. My experience with Java is limited and experience with C# non-existent.

      I perhaps don't understand your question, but if you want an object which can be created but not modified after its creation... just don't expose any "set" functions for parameters within that object - set all of the params in the "new" method. Nothing in Perl that I know of will prevent you from inheriting from such an object.

      I would think that normally your object should have a "has a" relationship to an immutable object rather than your object being an "is a" relationship to said object. Perl will allow you to do something stupid.

        Nothing in Perl that I know of will prevent you from inheriting from such an object.

        Ehhh… it's actually pretty easy to do in Moose/Moo/Class::Tiny. I mean, it's not rocket science to work around, but this should do the job:

        use v5.16; package Example::Phone { use Moo; has number => (is => 'ro', required => 1); sub call { ... } # Make final sub BUILD { my $self = shift; die(sprintf '%s is final; %s cannot inherit', __PACKAGE__, ref +($self)) unless ref($self) eq __PACKAGE__; } } package Example::Phone::Mobile { use Moo; extends 'Example::Phone'; sub send_sms { ... } } my $number1 = Example::Phone->new(number => 1); my $number2 = Example::Phone::Mobile->new(number => 2); # dies

      I don't see why that would be good practice.

      Let's create a telephone class:

      package Example::Phone { use Moo; has number => (is => 'ro', required => 1); sub call { ... } }

      Now let's use it:

      use Example::Phone; my $dad = Example::Phone->new(number => '+44 123 456 7890'); say "Dad's number is ", $dad->number; $dad->call();

      The object is immutable, in that once it's been instantiated, you can't use its public API to alter the number string.

      But that shouldn't stop us from subclassing it:

      package Example::Phone::Mobile { use Moo; extends 'Example::Phone'; sub send_sms { ... } }

      It doesn't in any way compromise the immutability of the parent class.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1194181]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2018-07-20 17:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?















    Results (438 votes). Check out past polls.

    Notices?