Dear monks,

this is not a serious problem, but I come across its variants quite frequently.

I have a method (say open_for_reading), which accepts hashref of parameters. Since it is quite important method I need all of its parameters to be understood. The open_for_reading method is overriden in a couple of subclasses, each of them understands more parameters.

my $context = $file->open_for_reading( {} ); my $context2 = $file->open_for_reading( { 'path' => $file } ); # OK my $context_derived = $file_derived->open_for_reading( { 'path' => $file, 'join_longca +lls' => 1 } ); # this should fail my $context_derived = $file->open_for_reading( { 'join_longcalls' => 1 + } );

Without the validation the code is something like:

package MyBaseClass; sub open_for_reading { my ($this, $params_ref) = @_; $params_ref ||= {}; return $this->get_context('path' => $params_ref->{'path'} || $this +->path); } package MyDerivedClass; sub open_for_reading { my ($this, $params_ref) = @_; $params_ref ||= {}; my $context = $this->SUPER::open_for_reading(); if ($params_ref->{'join_longcalls'}){ ... modify context } return $context; }

For parameter validation I found Params::Validate from CPAN. The only way I was able to add the validation is like this:

package MyBaseClass; sub open_for_reading_validation_spec { return { 'path' => 0, }; } sub open_for_reading { my ($this, $params_ref) = @_; $params_ref ||= {}; Params::Validate::validate($params_ref, $this->open_for_reading_va +lidation_spec); return $this->do_open_for_reading($params_ref); } sub do_open_for_reading { my ($this, $params_ref) = @_; return $this->get_context('path' => $params_ref->{'path'} || $this +->path); } package MyDerivedClass; use base qw(MyBaseClass); sub do_open_for_reading { my ($this, $params_ref) = @_; my $context = $this->SUPER::do_open_for_reading($params_ref); if ($params_ref->{'join_longcalls'}){ ... modify context } return $context; } sub open_for_reading_validation_spec { my ($this) = @_; return { %{$this->SUPER::open_for_reading_validation_spec}, 'join_longcalls' => 0, }; }

Instead of one method I have three:

I can live with three methods, but besides open_for_reading there are also open_for_writing, open_for_processing, ... so whole interface suddenly "triplicates".

Do you think is there a different solution?

Even without the validation there is a "naming" problem of its own. I have an interface method which does initialization and cleanup, and between these two blocks is a code to be overriden in subclasses.

sub method { my $this = shift; $this->do_some_initialization; $this->do_something_which_can_be_overriden_in_subclasses(); $this->do_some_cleanup; }

I put the inner block into separate method, but I often have problem to name it. Do you use some naming convention for the "executive" methods? Prefixes (do_, exec_)? Postfixes (_body)?


In reply to Method parameters validation and inheritance by roman

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.