Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

comment on

( [id://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

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (7)
As of 2024-04-18 17:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found