I want to pass a lexical file handle to a subroutine using a named argument, but the following does not compile:
#!/usr/bin/perl -w
use strict;
my $log_fh;
my $logname = "my.log";
sub primitive {
my ($fh, $m) = @_;
print $fh $m;
}
sub sophisticated {
my ($args) = @_;
print $args->{m};
print $args->{fh} $args->{m} ;
}
open $log_fh, ">", $logname;
print $log_fh "Today I learned ...\n";
primitive($log_fh,"... the old way works ...\n");
sophisticated({
fh=>$log_fh,
m=>"... and the new way requires an intervention by SO.",
});
close $log_fh;
The complaint is:
Scalar found where operator expected at ./lexical.file.handle.pl line 15, near
} $args"
(Missing operator before $args?)
$ perl --version
This is perl, v5.10.1
It works O.K. when I use the primitive technique of passing arguments, and the named-argument hash technique works for the message portion, just not for the file handle portion. Do I need a new version of print ?
You can pass various arguments to a Perl subroutine like you do in any other programming language and they can be accessed inside the function using the special array @_. Thus the first argument to the function is in [0],thesecondisin_[1], and so on.
Passing by reference allows the function to change the original value of a variable. When the values of the elements in the argument arrays @_ are changed, the values of the corresponding arguments will also change. This is what passing parameters by reference does.
Passing Lists or Arrays to a Subroutine: An array or list can be passed to the subroutine as a parameter and an array variable @_ is used to accept the list value inside of the subroutine or function.
A Perl subroutine or function is a group of statements that together performs a task. You can divide up your code into separate subroutines. How you divide up your code among different subroutines is up to you, but logically the division usually is so each function performs a specific task.
When you've got a complex expression that returns a filehandle (like $args->{fh}
) you'll need to disambiguate the syntax a bit by adding some extra curlies:
print { $args->{fh} } $args->{m};
This is due to the weird way the print
operator is designed, with no comma between the filehandle and the list of stuff to print.
Alternatively, you could grab the filehandle out of your arguments hashref first, e.g.
my $fh = $args->{fh};
print $fh $args->{m};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With