http://www.perlmonks.org?node_id=238599


in reply to RFC: Class::Proxy::MethodChain

Sometimes it's amazing how simple things can really turn out to be. At Re^5: RFC: Class::Proxy::MethodChain I said
[H]ow I long for the beauty of saying something like
given(Gtk::FileDialog->new()) { .ok_button.label("Load"); .cancel_button.label("Exit"); .connect_signal(destroy => sub { ... }); # ... }
Then I went on to abuse map to almost get there. Well, guess what - I can emulate the exact same thing (modulo syntax) in three lines Perl 5 that could hardly be simpler:
sub for_obj( local $_ = shift; shift->(); $_; }
which lets me write
my $window = for_obj(Gtk::Window->new("toplevel"), sub { $_->signal_connect(delete => sub { Gtk->exit(0) }); $_->set_title("Test"); $_->border_width(15); $_->add(for_obj(Gtk::Button->new("Quit") ,sub { $_->signal_connect(clicked => sub { Gtk->exit(0) }); $_->show; }); $_->show; });

It can be that simple. Even the snippet at multiple method calls against the same object (f.ex GUI programming) is a dozen times more effort than necessary. (I added an update there pointing here.)

I really need to get a handle on my hubris..

Update: or simply

sub for_obj { $_[1]->() for $_[0]; $_[0] }

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^2: RFC: Class::Proxy::MethodChain
by adrianh (Chancellor) on Feb 26, 2003 at 00:10 UTC

    Personal taste - but I'd have the sub first to keep it like map, grep, et al.

    sub apply_chain (&$) { local $_ = $_[1]; $_[0]->(); $_; } my $window = apply_chain { $_->signal_connect(delete => sub { Gtk->exit(0) }); $_->set_title("Test"); $_->border_width(15); $_->add( apply_chain { $_->signal_connect(clicked => sub { Gtk->exit(0) }); $_->show; } Gtk::Button->new("Quit") ); $_->show; } Gtk::Window->new("toplevel");
      The point of writing that function was that using map makes it read out of order - the new is at the bottom. Reversing the arguments on for_obj makes it practically the same thing as map so I would just stick with that one then.

      Makeshifts last the longest.

        Order is relative. Since everything else in perl that applies something to something else has the application block first that way reads more naturally to me in perl.

        To-mah-to. To-may-to. :-)

        Roll on perl6. With ~> and <~ and we can both be happy :-)

Re: Re: RFC: Class::Proxy::MethodChain
by Juerd (Abbot) on Feb 26, 2003 at 07:30 UTC

    my $window = for_obj(Gtk::Window->new("toplevel"), sub { $_->signal_connect(delete => sub { Gtk->exit(0) }); $_->set_title("Test"); $_->border_width(15); $_->add(for_obj(Gtk::Button->new("Quit") ,sub { $_->signal_connect(clicked => sub { Gtk->exit(0) }); $_->show; $_ }); $_->show; });

    I think I like explicit stuff better:

    my $window = do { local $_ = Gtk::Window->new('toplevel'); $_->signal_connect(delete => sub { Gtk->exit(0) }); $_->set_title('Test'); $_->border_width(15); $_->add( do { local $_ = Gtk::Button->new('Quit'); $_->signal_connect(clicked => sub { Gtk->exit(0) }); $_->show; $_; } ); $_->show; $_; };
    Sure, it takes more lines, but imho it's less messy, and much clearer. By the way - why is there a lone $_ in your inner for_obj?

    Juerd
    - http://juerd.nl/
    - spamcollector_perlmonks@juerd.nl (do not use).
    

      Because I had forgotten to convert that block from map syntax at first; when I did, I forgot to remove the $_. Fixed.

      Makeshifts last the longest.

Re: Re: RFC: Class::Proxy::MethodChain
by sauoq (Abbot) on Feb 26, 2003 at 00:58 UTC

    This is much better. :-)

    -sauoq
    "My two cents aren't worth a dime.";