Current Perl documentation can be found at perldoc.perl.org.
Here is our local, out-dated (pre-5.6) version:
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 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).