in reply to Re^2: Perl OOP
in thread Perl OOP

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.

Replies are listed 'Best First'.
Re^4: Perl OOP
by tobyink (Canon) on Jul 05, 2017 at 09:24 UTC

    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

      Ehhhhhhhhhhhhhhh…

      package Example::Phone { use Moo; has number => (is => 'ro', required => 1); sub call { ... } sub BUILD { use MooseX::Final; assert_final( my $self = shift ); } }