A rectangle class might have horizontal_stretch and vertical_stretch methods which stretch a rectangle in one direction. Square is a subclass of rectangle, but if you stretch a square in one direction, it's no longer a square.

Generalising the issue: mutator methods in the parent class might invalidate constraints imposed by the child class.

The square—rectangle problem (a.k.a. the circle—ellipse problem) is often seen as a demonstration of why subclassing is evil. I prefer to see it as a demonstration of why mutable objects are evil.

Here's a perfectly consistent implementation of a Square and Rectangle class using immutable objects and subclassing...

use Moops; class Rectangle using Moose :ro { has height => (isa => Num, required => true); has width => (isa => Num, required => true); has colour => (isa => Str, default => "black"); method area () { $self->height * $self->width; } method perimeter () { 2 * ($self->height + $self->width); } # Here's a private method; it creates a clone of # the current object, but allows some attributes to # be changed. # method my $_but (%args) { __PACKAGE__->new(%$self, %args); } method paint (Str $colour) { $self->$_but( colour => $colour ); } method horizontal_stretch (Num $factor) { my $new_width = $self->width * $factor; $self->$_but( width => $new_width ); } method vertical_stretch (Num $factor) { my $new_height = $self->height * $factor; $self->$_but( height => $new_height ); } method grow (Num $factor) { $self->horizontal_stretch($factor)->vertical_stretch($factor); } } class Square extends Rectangle using Moose :ro { around BUILDARGS (@args) { my $params = $self->$next(@args); $params->{height} //= $params->{width}; $params->{width} //= $params->{height}; return $params; } method BUILD { confess "Not a square" unless $self->width == $self->height; } } my $square = Square->new(width => 12); print $square->dump; my $painted = $square->paint("red"); print $painted->dump; my $grown = $painted->vertical_stretch(2.5); print $grown->dump;
/a

In reply to Re^5: When to Use Object Oriented approach in Perl? (RFC) by tobyink
in thread When to Use Object Oriented approach in Perl? (RFC) by thanos1983

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.