[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl] coooool

I had a thought yesterday and wrote to p5p about it, and Tom Christiansen
replied with an ingenious bit of code that allows you to call object
methods without specifying the method immeidately before it.  So instead of:

  #!perl -wl
  use Mac::Glue ':glue';

  my $f = new Mac::Glue 'Finder';
  my @files = $f->get($f->obj(
    files => glueAll, of => 'Desktop'), as => 'string');
  print join "\n", @files;

I can do:

  #!perl -wl
  use UnderMethods;  # the cool code
  use Mac::Glue ':glue';

  for (my $f = new Mac::Glue 'Finder') {
    my @files = get(obj(files => glueAll, of => 'Desktop'), as => 'string');
    print join "\n", @files;

Basically, $f->get and $f->obj become just get() and obj().  This can be a
great thing when you have a dozen event and obj() calls.  Of course, if you
have an event called "open", or you have an event called "get" and you've
imported another function called "get" (maybe with LWP::Simple), you would
need to use $_-> so Perl knows that you want a method, not a function call.

Anyway, here's the code, with some modifications of my own.  It exports an
AUTOLOAD sub to the calling package.  The for () sets $_ (which is global!)
to the object, and then we can access the object through $_ in AUTOLOAD.
Pretty nifty.

package UnderMethods;

use strict;
use Carp;
use vars '$AUTOLOAD';

sub import {
    no strict 'refs';
    *{ caller() . "::AUTOLOAD" } = \&AUTOLOAD;

    my $ref = ref;
    croak "Undefined subroutine &$AUTOLOAD called" unless $ref;
    (my $name = $AUTOLOAD) =~ s/.*:://;
    my $func = $_->can($name);
    confess "Can't call method `$name' in $ref" unless $func;
    unshift @_, $_;
    goto &$func;


Chris Nandor          mailto:pudge@pobox.com         http://pudge.net/
%PGPKey = ('B76E72AD', [1024, '0824090B CE73CA10  1FF77F13 8180B6B6'])

===== Want to unsubscribe from this list?
===== Send mail with body "unsubscribe" to macperl-request@macperl.org