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_longcalls' => 1 } ); # this should fail my $context_derived = $file->open_for_reading( { 'join_longcalls' => 1 } ); #### 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; } #### 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_validation_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, }; } #### sub method { my $this = shift; $this->do_some_initialization; $this->do_something_which_can_be_overriden_in_subclasses(); $this->do_some_cleanup; }