arunkumar.rk141 has asked for the wisdom of the Perl Monks concerning the following question:

i'm trying to update a file reading logic in modules. But it is not giving the expected results.

with the below code, file reading is not happening inside the main file. Could you pls advise on this? Also you can suggest best practise of reading the files(passed as either arg or as an input through STDIN) inside a module without making any changes in main file

fileread.pl:

use file_read; my $a=0; while(<STDIN>){ $a+=1; } print "$a";

file_read.pm:

package file_read; while(<STDIN>){ print; } 1;
perl fileread.pl </tmp/file

Output : contents of the /tmp/file and $a value is printed as 0 but not 1

2020-06-16 Athanasius added <code> and <p> tags.

Replies are listed 'Best First'.
Re: Usage of STDIN for file reading inside a module
by haukex (Archbishop) on Jun 15, 2020 at 09:06 UTC

    The code in the module is reading everything from STDIN, that's why there's nothing left for the main code to read. There are two issues with the design: normally, modules don't have code that executes when you load them except initialization for the module itself, and second, a module normally wouldn't access STDIN. More commonly, the module would contain a sub that the main code can call and that would take a filehandle as an argument. If you think you need the design as you showed it, then I suspect an XY Problem and it'd be better if you explained what it is you're trying to do.

    P.S. Please use <code> tags to format your code.

Re: Usage of STDIN for file reading inside a module
by jcb (Parson) on Jun 16, 2020 at 01:51 UTC

    I will second haukex here, STDIN is a global resource and modules really should not be explicitly using it unless that is their purpose, as in Term::ReadLine or similar. Further, modules should very rarely execute code at top-level and the convention is that module names in all lowercase are reserved for pragmas like strict and warnings.

    There are several much better solutions, but unless you describe what you are trying to do, we will not really be able to help you. If you really are misusing the module system as a subroutine call, perhaps this will help: (untested)

    use strict; use warnings; sub file_read { local $.; my $fh = shift; while (<$fh>) { print } return $.; } print file_read(\*STDIN), "\n";

    See perlvar for what the $. variable does and perlreftut for a quick introduction to "that funny \ thing".