Quick Search for:  in language:    
Heres
   Code/Articles » |  Newest/Best » |  Community » |  Jobs » |  Other » |  Goto » | 
CategoriesSearch Newest CodeCoding ContestCode of the DayAsk A ProJobsUpload
Perl Stats

 Code: 75,331. lines
 Jobs: 26. postings

 How to support the site

 
Sponsored by:

 
You are in:
 
Login





Latest Code Ticker for Perl
Message Sender
By sp on 1/15


Click here to see a screenshot of this code!Mailing List v2.0
By Aaron L. Anderson on 1/7

(Screen Shot)

ShowIMG
By Jeff Mills on 1/5


Click here to put this ticker on your site!


Add this ticker to your desktop!


Daily Code Email
To join the 'Code of the Day' Mailing List click here!

Affiliate Sites



 
 
   

How can I pass/return a {Function, FileHandle, Array, Hash, Method, Regexp}?

Print
Email
 

Submitted on: 7/29/2000 10:48:12 PM
By: Found on the World Wide Web 
Level: Advanced
User Rating: By 2 Users
Compatibility:5.0 (all versions), 4.0 (all versions)

Users have accessed this article 8365 times.
 
 
     Here's how...

 

With the exception of regexps, you need to pass references to these objects. See Pass by Reference for this particular question, and the perlref manpage for information on references.

Passing Variables and Functions

Regular variables and functions are quite easy: just pass in a reference to an existing or anonymous variable or function:

 

 func( \$some_scalar );
    

 

 func( \@some_array );
    func( [ 1 .. 10 ] );
    

 

 func( \%some_hash );
    func( { this => 10, that => 20 } );
    

 

 func( \&some;_func );
    func( sub { $_[0] ** $_[1] } );
    
Passing Filehandles

To pass filehandles to subroutines, use the *FH or \*FH notations. These are ``typeglobs'' - see Typeglobs and Filehandles and especially Pass by Reference for more information.

Here's an excerpt:

If you're passing around filehandles, you could usually just use the bare typeglob, like *STDOUT, but typeglobs references would be better because they'll still work properly under use strict 'refs'. For example:

 

 splutter(\*STDOUT);
    sub splutter {
    my $fh = shift;
    print $fh "her um well a hmmm\n";
    }
    

 

 $rec = get_rec(\*STDIN);
    sub get_rec {
    my $fh = shift;
    return scalar <$fh>;
    }
    

If you're planning on generating new filehandles, you could do this:

 

 sub openit {
    my $name = shift;
    local *FH;
    return open (FH, $path) ? *FH : undef;
    }
    $fh = openit('< /etc/motd');
    print <$fh>;
    
Passing Regexps

To pass regexps around, you'll need to either use one of the highly experimental regular expression modules from CPAN (Nick Ing-Simmons's Regexp or Ilya Zakharevich's Devel::Regexp), pass around strings and use an exception-trapping eval, or else be very, very clever. Here's an example of how to pass in a string to be regexp compared:

 

 sub compare($$) {
    my ($val1, $regexp) = @_;
    my $retval = eval { $val =~ /$regexp/ };
    die if $@;
    return $retval;
    }
    

 

 $match = compare("old McDonald", q/d.*D/);
    

Make sure you never say something like this:

 

 return eval "\$val =~ /$regexp/"; # WRONG
    

or someone can sneak shell escapes into the regexp due to the double interpolation of the eval and the double-quoted string. For example:

 

 $pattern_of_evil = 'danger ${ system("rm -rf * &") } danger';
    

 

 eval "\$string =~ /$pattern_of_evil/";
    

Those preferring to be very, very clever might see the O'Reilly book, Mastering Regular Expressions, by Jeffrey Friedl. Page 273's Build_MatchMany_Function() is particularly interesting. A complete citation of this book is given in the perlfaq2 manpage.

 

Passing Methods

To pass an object method into a subroutine, you can do this:

 

 call_a_lot(10, $some_obj, "methname")
    sub call_a_lot {
    my ($count, $widget, $trick) = @_;
    for (my $i = 0; $i < $count; $i++) {
    $widget->$trick();
    }
    }
    

Or you can use a closure to bundle up the object and its method call and arguments:

 

 my $whatnot = sub { $some_obj->obfuscate(@args) };
    func($whatnot);
    sub func {
    my $code = shift;
    &$code();
    }
    

You could also investigate the can() method in the UNIVERSAL class (part of the standard perl distribution).


Other 103 submission(s) by this author

 

 
Report Bad Submission
Use this form to notify us if this entry should be deleted (i.e contains no code, is a virus, etc.).
Reason:
 
Your Vote!

What do you think of this article(in the Advanced category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor See Voting Log
 
Other User Comments

 There are no comments on this submission.
 
Add Your Feedback!
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.

NOTICE: The author of this article has been kind enough to share it with you.  If you have a criticism, please state it politely or it will be deleted.

For feedback not related to this particular article, please click here.
 
Name:
Comment:

 

Categories | Articles and Tutorials | Advanced Search | Recommended Reading | Upload | Newest Code | Code of the Month | Code of the Day | All Time Hall of Fame | Coding Contest | Search for a job | Post a Job | Ask a Pro Discussion Forum | Live Chat | Feedback | Customize | Perl Home | Site Home | Other Sites | About the Site | Feedback | Link to the Site | Awards | Advertising | Privacy

Copyright© 1997 by Exhedra Solutions, Inc. All Rights Reserved.  By using this site you agree to its Terms and Conditions.  Planet Source Code (tm) and the phrase "Dream It. Code It" (tm) are trademarks of Exhedra Solutions, Inc.