Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Comment on

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

I just wrote a module based on a concept that has been floating around in my head for a while. It looks fairly complete already, but is just an initial draft. I'd like some comments on what I should be wary of, what could be done better, things I might add or improve, and so on. Basically, any kind of feedback you come up with - I wanna hear it.

It follows the same goal as my quick multiple method calls against the same object (f.ex GUI programming) snippet - I suggest you take a quick look at it before reading on.

To reiterate, the idea is to achieve a smoother experience for those who're using classes with many setter methods that don't usually return anything meaningful or interesting. One such module is Gtk, the Perl binding of the GTK+ toolkit.

The idea is rather simple: instead of calling methods directly on the object in question, you call them on a proxy object wrapped around it. The proxy methods return $self after storing away the return value, so now you can chain calls to multiple methods.

Of course you can also retrieve the return value of the last method call of the chain.

Furthermore, to make an obvious concept a little more exciting, there are provisions for the case of methods returning aggregated objects, such as $file_dialog->ok_button->signal_connect(..);. In that case you can pass a coderef, which will be called with the results as its parameters. With an additional convenience function that assumes a single object reference as the returned value and wraps it into a proxy of its own, you can call another chain of methods on the return value of a method such as a ->ok_button in the above example.

Once I had my goals and desired approach straight, there was surprisingly little code to write:

#!/usr/bin/perl -w use strict; package Class::Proxy::MethodChain; use vars qw($AUTOLOAD); use constant OBJ => 0; use constant RET => 1; # handles method and constructor delegation sub AUTOLOAD { my $self = shift; $AUTOLOAD =~ s/^.*:://; if(ref $self) { $self->[RET] = [ $self->[OBJ]->$AUTOLOAD(@_) ]; $self; } else { bless [($self->$AUTOLOAD(@_))x2]; } } # wrap existing object sub wrap { my $self = shift; bless [(shift)x2]; } # get last return value or pass it to a callback without # breaking the chain sub ret_val { my $self = shift; if(@_) { my $callback = shift; local *_ = $self->[RET]; &$callback(@_); return $self; } else { return @{$self->[RET]}; } } # convenience function for when the return value is an objref sub ret_wrap { my $self = shift; my $wrapped = __PACKAGE__->wrap($self->[RET]->[0]); if(@_) { my $callback = shift; $callback->($wrapped); return $self; } else { return $wrapped; } } # allow calling methods with the same names as CPMC's sub call { $AUTOLOAD = shift; goto &AUTOLOAD; } sub DESTROY() {} 1;
Using this, the code from multiple method calls against the same object (f.ex GUI programming) reads a lot more naturally:
my $window = Gtk::Window ->Class::Proxy::MethodChain::new("toplevel") ->signal_connect(delete => sub { Gtk->main_quit }) ->set_title("Test") ->border_width(15) ->add(Gtk::Button ->Class::Proxy::MethodChain::new("Quit") ->signal_connect(clicked => sub { Gtk->main_quit }) ->show ) ->show;
I intend to put this on CPAN, so I'd really appreciate comments.

Makeshifts last the longest.


In reply to RFC: Class::Proxy::MethodChain by Aristotle

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!
  • 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
  • Outside of code tags, you may need to use entities for some characters:
            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?
    Username:
    Password:

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

    How do I use this? | Other CB clients
    Other Users?
    Others avoiding work at the Monastery: (7)
    As of 2014-12-21 07:09 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Is guessing a good strategy for surviving in the IT business?





      Results (104 votes), past polls