Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Avoiding global variables when I need to supply a callback

by matija (Priest)
on Jul 22, 2004 at 11:12 UTC ( #376538=perlquestion: print w/ replies, xml ) Need Help??
matija has asked for the wisdom of the Perl Monks concerning the following question:

Part of my code needs a list of URLs that are kept in a text message. Thanks to PodMaster I found the right tool for finding the URLs in URI::Find.

There is a small hitch, though: I want a function that returns an array of URLs. The synopsis for using URI::Find is this:

require URI::Find; my $finder = URI::Find->new(\&callback); $how_many_found = $finder->find(\$text);
Now, I could easily use the callback function to store the URLs in a global array variable. But what if I want them in an array that is local to the function calling URI::Find? Is there any way to pass a reference to a target array to the callback function? Any other ideas I could try?

Comment on Avoiding global variables when I need to supply a callback
Download Code
Re: Avoiding global variables when I need to supply a callback
by gaal (Parson) on Jul 22, 2004 at 11:26 UTC
    If I understand your problem correctly, what you need is a closure:
    { # in some scope my @array = ( qw(some data) ); my $finder = URI::Find->new(sub { # this callback code sees @array as it was when the closure wa +s created. }); }
    Read up on closures in perlsub and perlref.
Re: Avoiding global variables when I need to supply a callback
by beable (Friar) on Jul 22, 2004 at 11:39 UTC
    You can use an anonymous subroutine for the callback, which will let you put the URIs you find into an array which isn't global:
    #!/usr/bin/perl use strict; use warnings; use URI::Find; find_em(); sub find_em { my $text = "http://www.goolge.com/ blah httg://kew.org ftp://127.0 +.0.1/warez"; my @uris = (); my $finder = URI::Find->new(sub{my ($uri, $text) = @_; push @uris, + $uri;}); my $how_many_found = $finder->find(\$text); print("uris are @uris\n"); } __END__
Re: Avoiding global variables when I need to supply a callback
by borisz (Canon) on Jul 22, 2004 at 11:42 UTC
    Use a closure.
    sub grab_uri{ my @uris; my $finder = URI::Find->new(sub { my($uri, $orig_uri) = @_; push @uris, $uri; $uri }); $finder->find(\$d); \@uris; }
    Boris

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://376538]
Approved by gellyfish
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2014-12-21 21:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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





    Results (108 votes), past polls