http://www.perlmonks.org?node_id=1159577


in reply to Re: Importing Data and Exporting Data Issues
in thread Importing Data and Exporting Data Issues

1. Done!

2. Should I declare @lines after opening the files then? Should I declare $ave in my average function?

3. I'm using -e to check and see if the file even exists before attempting to open and read from it.

4. I have not used lexical file handles before, are they used similarly to how file handles are used normally?

5. I was attempting to put all my data into an array so my functions would read it and work accordingly.

6. Experiment, meant to change it back to  (<FIN>)

7. Experiment again, was originally @lines.

8. Done!

Replies are listed 'Best First'.
Re^3: Importing Data and Exporting Data Issues
by Marshall (Canon) on Apr 05, 2016 at 06:55 UTC
    I'll address one point. Grandfather gave good advice.

    3. -e vs -f. The documentation is not super clear about this. Basically a directory is also a "file", albeit a special one. The -e test will return true if the name is a directory or some other weirdo things that aren't relevant now. The -f test will return true if (a)the file exists AND (b)the file is a "plain file". Use the -f test. The -e test can return true for some things that aren't simple readable files.

Re^3: Importing Data and Exporting Data Issues
by GrandFather (Saint) on Apr 05, 2016 at 12:02 UTC

    Good answers. Mind you, that does show a degree of unwarranted laziness in cleaning up your code for posting! In fact, if you'd cleaned up your code you quite likely would have fixed the problem.

    However, to continue the lesson lets see what the code might look like if you follow the advice. Consider:

    #!/usr/bin/perl use strict; use warnings; my $inputData = <<IN; 1 2 3 4 5 6 7 8 9 10 IN open my $fIn, '<', \$inputData; chomp (my @lines = <$fIn>); printf "Average: %.2f\n", average(@lines); printf "Largest: %d\n", largest(@lines); sub average { my $sum = 0; $sum += $_ for @_; return $sum / @_; } sub largest { my $max = shift @_; for my $value (@lines) { $max = $value if $value > $max; } return $max; }

    Prints:

    Average: 5.50 Largest: 10

    Note that I've stripped out the code dealing with getting a file name, validating it and reading a file from disk. Instead I "open" a string as a file. That gives me a quick test framework so I can easily make changes to the code and test them.

    $fIn is a lexical file handle (variables declared with my are lexical). Lexical file handles have the advantage that strict can better check their usage so you have fewer issues with misspelled file handle identifiers. When lexical file handles go out of scope (execution leaves the block the variable was declared in) the file is closed so you mostly avoid files remaining open too long if you forget a close. Aside from that lexical file handles work pretty much the same.

    Note that we declare @lines where we assign content to it and we don't need $avg at all.

    Premature optimization is the root of all job security