Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

i am having a file handle
open KERLIS, "<$lis_file"; @lis_array=<KERLIS>;

i want to write a function to which i want to pass the contents of file i had read
there are two ways , one is to pass array and other is to pass file handle.
i had tried with passing array to function but i read some where pasing array is not optimized way of working
so i thought if i can pass file handle to fucntion.
is it posible to pass file handle to function / subroutine and if yes how can i do for my case

Edit: g0n - code tags

Replies are listed 'Best First'.
Re: passing file handle to functions
by Samy_rio (Vicar) on May 18, 2006 at 05:53 UTC

    Hi, if I have understood your question correctly then try this,

    use strict; use warnings; #####Function 1############# open (FF, "sample.xml")||die $!; my @con = <FF>; close(FF); #Passing Array to a function &function1(\@con); #####Function 2############# open (FF, "sample.xml")||die $!; #Passing File handle to a function &function2(\*FF); close(FF); sub function1{ my ($con) = @_; #Dereference the array my @con = @{$con}; $,="\n"; print @con; } sub function2{ my ($con) = @_; print <$con>; }

    View these How (Not) To Ask A Question and How do I post a question effectively?

    Regards,
    Velusamy R.


    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

Re: passing file handle to functions
by davorg (Chancellor) on May 18, 2006 at 07:58 UTC

    You probably just need to pass a reference to the array into the function:

    your_function(\@lis_array);

    But if you really want to pass a file handle around then create a lexical filehandle and use that:

    open my $kerlis, '<', $lis_file or die $!; your_function($kerlis); sub your_function { my $fh = shift; while (<$fh>) { # do something } }

    People will recommend passing the typeglob into the function, but in my opinion that's a confusing hack that is no longer necessary with modern versions of Perl.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: passing file handle to functions
by TedPride (Priest) on May 18, 2006 at 08:13 UTC
    If using a separate function for data processing, it's generally best to keep the file reading out of it. I'd just pass a reference to the array. Heck, you can pass the array itself - Perl passes it internally as a reference anyway, and you don't lose any efficiency so long as you don't assign (copy) the contents.

    GOOD:

    fast(@data); sub fast { my $x = $_[0]; }
    BAD:
    slow(@data); sub slow { my @arr = @_; my $x = $arr[0]; }
    ALSO GOOD (but not as pretty):
    fast(\@data); sub fast { my $arr = $_[0]; my $x = $arr->[0]; }
Re: passing file handle to functions
by ioannis (Abbot) on May 18, 2006 at 07:13 UTC
    If you pass a glob, you can pass both the filehandle and the array with one stone -- the filehandle can always be reopened:
    no strict 'vars'; use Fatal qw(open); open local(*KERLIS) , $file; @KERLIS = <I>; close KERLIS; passboth( *KERLIS ); sub passboth { local *FH = shift; # print @FH; # open *FH, $file; }
Re: passing file handle to functions
by UnderMine (Friar) on May 18, 2006 at 06:04 UTC
    Why not use a variable for your filehandle?

    Example from the perlfunc docs

    # process argument list of files along with any includes foreach $file (@ARGV) { process($file, 'fh00'); } sub process { my($filename, $input) = @_; $input++; # this is a string increment unless (open($input, $filename)) { print STDERR "Can't open $filename: $!\n"; return; } local $_; while (<$input>) { # note use of indirection if (/^#include "(.*)"/) { process($1, $input); next; } #... # whatever } } See perliol for detailed info on PerlIO.

    Hope it help

    UnderMine

      foreach $file (@ARGV) { process($file, 'fh00'); } sub process { my($filename, $input) = @_; $input++; # this is a string increment unless (open($input, $filename)) { print STDERR "Can't open $filename: $!\n"; return; } local $_; while (<$input>) { # note use of indirection if (/^#include "(.*)"/) { process($1, $input); next; } #... # whatever } }

      Did you try that under "use strict"?

      Can't use string ("fh01") as a symbol ref while "strict refs" in use

      From perldoc open:

      If FILEHANDLE is an undefined scalar variable (or array or hash element) the variable is assigned a reference to a new anonymous filehandle, otherwise if FILEHANDLE is an expression, its value is used as the name of the real filehandle wanted. (This is considered a symbolic reference, so use strict 'refs' should not be in effect.)

      So what you're trying only works with "use strict" if the variable that you use for the filehandle contains an undefined value.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        True. I was quoting directly from perldoc perlfunc examples for open. Which seams different from the perldoc open.

        UnderMine