Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: How to pass and use a lexical file handle to a subroutine as a named argument?

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 ?

like image 613
Thomas L Holaday Avatar asked Jun 25 '10 18:06

Thomas L Holaday


People also ask

How do you pass arguments to a subroutine in Perl?

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.

How do I pass a variable by reference in Perl?

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.

What is the variable used to get the parameters passed to the subroutine?

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.

How do you call and identify a subroutine in Perl explain with example?

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.


1 Answers

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};
like image 80
friedo Avatar answered Nov 10 '22 10:11

friedo