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:
Using this, the code from multiple method calls against the same object (f.ex GUI programming) reads a lot more naturally:#!/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;
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;
Makeshifts last the longest.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: RFC: Class::Proxy::MethodChain
by Aristotle (Chancellor) on Feb 25, 2003 at 23:07 UTC | |
by adrianh (Chancellor) on Feb 26, 2003 at 00:10 UTC | |
by Aristotle (Chancellor) on Feb 26, 2003 at 07:09 UTC | |
by adrianh (Chancellor) on Feb 26, 2003 at 10:29 UTC | |
by Aristotle (Chancellor) on Feb 27, 2003 at 19:35 UTC | |
by Juerd (Abbot) on Feb 26, 2003 at 07:30 UTC | |
by Aristotle (Chancellor) on Feb 27, 2003 at 19:32 UTC | |
by sauoq (Abbot) on Feb 26, 2003 at 00:58 UTC | |
Re: RFC: Class::Proxy::MethodChain
by Aristotle (Chancellor) on Feb 21, 2003 at 15:54 UTC | |
by sauoq (Abbot) on Feb 21, 2003 at 20:30 UTC | |
by Aristotle (Chancellor) on Feb 21, 2003 at 21:38 UTC | |
by sauoq (Abbot) on Feb 24, 2003 at 22:15 UTC | |
by Aristotle (Chancellor) on Feb 24, 2003 at 23:37 UTC | |
Re: RFC: Class::Proxy::MethodChain
by adrianh (Chancellor) on Feb 22, 2003 at 14:00 UTC | |
by Aristotle (Chancellor) on Feb 22, 2003 at 15:42 UTC | |
by adrianh (Chancellor) on Feb 23, 2003 at 02:14 UTC | |
Re: RFC: Class::Proxy::MethodChain
by runrig (Abbot) on Feb 25, 2003 at 00:04 UTC |