Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I'm looking for a way to eliminate common code in a lot of methods that deals with passing on the call context. Any suggestions on how I could restructure my code to be less repetitive are welcome.

I have a set of methods that have a dual life. When called in void context, they act as mutators, and when called in non-void context, they return a modified copy. As an example (and my use case), consider the methods to move the cursor of a text editor through a document.

The idea is to use them in the following setting:

$cursor->move_right(3); # move cursor three chars to the right $cursor->move_down(); # move cursor one line downwards # and my $left_pos = $cursor->move_left(1); # position one char to the left of the cursor my $start = $cursor->start_of_document();

I have many more such methods (end_of_document, ...) and they all look basically the same:

sub frobnicate_position { my ($self) = @_; my $obj; if (defined wantarray) { $obj = $self->copy(); } else { $obj = $self; } ... calculate new position here, ... set $obj->line() and $obj->column() return $obj };

For every method, the calculation can range from pretty simple to moderately complex, but the calculation code seldom spans more than three lines.

What I'm aiming for is to eliminate or reduce the 8 common lines of setup that every method will have, as the repetition strikes me as not elegant. One idea I have is to use a wrapper around the real meat:

sub positional_mutator(&;$) { my ($worker,$name) = @_; no strict 'refs'; *{$name} = sub { my $self = shift; my $obj; if (defined wantarray) { $obj = $self->copy(); } else { $obj = $self; }; $worker->($obj,@_); } }; positional_mutator { my ($obj,@args) = @_; ... calculate new position here }, 'frobnicate_position';

That way, I'll eliminate these setup lines evaluating the context, at the price of some syntactical weirdness - I'll have to install the method through my wrapper and the name now comes after the code. That isn't completely elegant. I could go through Attribute::Handler, but that strikes me as the nuclear solution to weed removal - it also doesn't play well when the module isn't loaded through use, at least when loading the module by use_ok.

In reply to How to best pass on the context / wantarray? by Corion

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others browsing the Monastery: (5)
    As of 2018-03-20 03:07 GMT
    Find Nodes?
      Voting Booth?
      When I think of a mole I think of:

      Results (247 votes). Check out past polls.