Professional Web Applications Themes

Opening file($ARGV) with Getopt - failing - PERL Beginners

Hi, Why my code below fail to open and print the file contents when I do: perl mycode.pl -f filename Regards, Edward WIJAYA SINGAPORE __BEGIN__ use strict; use warnings; use Getopt::Std; use vars qw($f); getopts('f:'); my $f = $ARGV[0]; open ( INFILE, '<', $f) or die "$0 : failed to open input file $f : $!\n"; close ( INFILE ); while ( <> ) { print $_; } __END__...

  1. #1

    Default Opening file($ARGV) with Getopt - failing

    Hi,
    Why my code below fail to open and
    print the file contents

    when I do:

    perl mycode.pl -f filename

    Regards,
    Edward WIJAYA
    SINGAPORE

    __BEGIN__
    use strict;
    use warnings;

    use Getopt::Std;
    use vars qw($f);
    getopts('f:');

    my $f = $ARGV[0];
    open ( INFILE, '<', $f)
    or die "$0 : failed to open input file $f : $!\n";
    close ( INFILE );


    while ( <> )
    {
    print $_;
    }
    __END__
    Edward Guest

  2. #2

    Default Re: Opening file($ARGV) with Getopt - failing

    Hi Edward!


    On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
    <com.sg> wrote: 

    Good Start! Those pragmas above are very helpful!
     

    The above is good, but is now obsolete. The preferred method is to
    use 'our' declarations
    Also, the 'getopts()' function creates variables of the form 'opt_*'
    where '*' is replaced with
    your option name. So, for example, you should have declared opt_f here:

    our $opt_f;
     

    This is good, I especially like the 'die' statement in case it
    fails. Good Job! It is relevant
    to note that opening a file to read is default, so the '<' was not
    necessary. However, it is
    nice to make it obvious which way you are opening the file (read
    only, write, or etc.). I
    might have written this as follows:

    open INFILE, "<$opt_f" or die "$0: failed to open input file $opt_f: $!";
     
    Why are you closing the file you just opened? Maybe it's because
    you don't understand
    the diamond ('<>') operator. The diamond operator will read the end
    of you command line
    and open each filename it finds there for processing. It allows you
    to write a Perl script
    that acts like any other UNIX process (e.g. cat, grep, etc ... ).
    In your code example,
    it appears as if you are trying NOT to use the diamond operator and
    force your user
    to input a single filename with the '-f' option. If this is the
    case, you don't want to close
    your 'INFILE' above until after you've used it! Like this:

    while( <INFILE> ) {
    print;
    }
     

    Inside this block, the '$_' variable is default and will be assigned
    the next line from
    the file that 'while' is processing. Because it is default, it is
    not necessary.
     

    Edward, I could write this script two ways. The first is the way I
    prefer and it doesn't use 'Getopt::Std' at all:

    #!/usr/bin/perl

    use warnings;
    use strict;

    while( <> ) {
    print;
    }

    That code above uses the diamond operator correctly. The diamond
    ('<>') operator reads the command line and processes each file name on
    the command line after your command! So, in a command called
    'perl_cat.pl' with a command line like:
    # perl_cat.pl foo.txt bar.txt
    The diamond operator will first open foo.txt (processed in the while
    loop) and print each line, then, open bar.txt and print each of it's
    lines!

    However, if you are really trying to use the 'Getopt::Std' module, I'd
    do it like this:

    #!/usr/bin/perl

    use warnings;
    use strict;

    our $opt_f;
    getopts( 'f:' );

    open INFILE, "<$opt_f" or die "$0: Can't open file $opt_f: $!";

    while( <INFILE> ) {
    print;
    }

    In the above code, unlike yours, I don't 'close' INFILE. That's
    because Perl will close it for me at the end of my code.

    I hope this helps!

    --Errin
    Errin Guest

  3. #3

    Default Re: Opening file($ARGV) with Getopt - failing

    Hi again, Edward!

    Just so you know, you should CC the list when you reply!

    On Tue, 28 Sep 2004 22:26:55 +0800, Edward Wijaya
    <com.sg> wrote: 
    > I need to use Getopt, as I will increase
    > the number of user given options.
    >
    > Regards
    > Edward WIJAYA
    >[/ref]

    I'm glad I could help!! Just wanted to mention one last thing. Just
    because you have to use Getopt::Std doesn't mean you can't ALSO use
    the diamond ('<>') operator. Let me demonstrate:

    #!/usr/bin/perl

    use warnings;
    use strict;
    use Getopt::Std;

    our $opt_p;
    getopts( 'p:' );

    if( $opt_p ) {
    print "You used the -p flag. The value passed was $opt_p\n";
    }

    while( <> ) {
    print;
    }

    The above will print out all the lines of the file found at the END of
    your command line (that's the diamond operator at work), but it will
    also allow you to specify some other option with a '-p'. So, if you
    have a text file called test.txt:
    Test Data
    More Test Data
    Other Test Data

    and you call the above program with this command line:
    # test_options.pl test.txt

    the output will be as follows:
    Test Data
    More Test Data
    Other Test Data

    if You instead use THIS command line:
    # test_options.pl -p foobar test.txt

    the output will be as follows:
    You used the -p flag. The value passed was foobar.
    Test Data
    More Test Data
    Other Test Data

    I hope that makes sense. Don't forget that the diamond operator will
    see more than one filename on that command line as well:

    # test_options.pl -p foobar test.txt test.txt
    You used the -p flag. The value passed was foobar.
    Test Data
    More Test Data
    Other Test Data
    Test Data
    More Test Data
    Other Test Data

    HTH
    --Errin
    Errin Guest

  4. #4

    Default Re: Opening file($ARGV) with Getopt - failing

    On Tue, 28 Sep 2004, Errin Ln wrote:
     
    >
    > The above is good, but is now obsolete.[/ref]

    That is debatable.

    Gather round, and listen to the story of a log handling utility
    written in perl, and a frustrated user. He's not a perl programmer,
    he's a Solaris sysadmin. For him, perl is just a tool, just another
    language. And the version of perl shipped with his Solaris is
    5.005_03.

    He is disinclined to build and install a new version of perl just
    to support a single tool. After all, he doesn't have to build
    new versions of awk, or new versions of C. Why should perl be any
    different?

    Trouble is, the author of this tool didn't agree. He had used
    our variables instead of my. Which, of course, don't work in
    5.005_03. The user was quite prepared to ditch the tool altogether
    and find another because it didn't Just Work. I suggested that he
    go through it replacing our with my and lo and behold, it worked.

    The moral of this story is that even if you have the latest and
    greatest perl, you shouldn't use the latest and greatest features
    unless you absolutely must. Because if you do you will severely
    limit who will use your code. our in particular is really only a
    convenience, saving a few key strokes at most. So don't use it.
    Ever.

    I'll buy a crate of beer for the first person who can show me some
    real-world code which absolutely requires our and can't be
    re-written to use my <update>or use vars (cos I meant to say that
    originally as well)</update>.

    <http://www.perlmonks.com/index.pl?node_id=393423>

    The latest & greatest is only worth using if:

    * it really does offer you something you need
    * it really does offer you something that wasn't available before
    * you really don't have to worry about portability
    * there really aren't downsides to using it

    For most people, in most cases, one or more of these won't be true.

    It's worth it to be aware of the downsides of using a modern feature
    like `our`, and to be confident that it really does make more sense to
    use it over some older approach. It may be that the new ways really are
    better -- I'm certainly not against progressing the language -- but if a
    new feature breaks otherwise good code, is it worthwhile?


    --
    Chris Devers
    Chris Guest

  5. #5

    Default Re: Opening file($ARGV) with Getopt - failing

    On Tue, 28 Sep 2004 15:26:08 -0400 (EDT), Chris Devers
    <com> wrote: 
    > >
    > > The above is good, but is now obsolete.[/ref]
    >
    > That is debatable.
    >
    > Gather round, and listen to the story of a log handling utility[/ref]

    <<SNIP>>
     

    So, what was the justification for changing 'use vars' to 'our'? Did
    the developers just want to shave down the keystrokes? Was it an
    understandability (is that a word?!) issue? Is there any (deep down,
    underneath it all) internal difference between the two? Is there a
    resource to read about this issue? (I did read the link you supplied,
    but it didn't go into WHY this changed.)

    The advice I was giving in this thread was based on the following
    quote in my 'perldoc Getopt::Std' doentation. (A quote from that):

    Note that, if your code is running under the recommended
    "use strict 'vars'" pragma, you will need to declare these
    package variables with "our":

    our($opt_foo, $opt_bar);


    Later in the docs it DOES say that if you don't want to declare these
    as global variables, 'getopts()' will accept a hash reference.
    (Another quote):

    For those of you who don't like additional global variables
    being created, getopt() and getopts() will also accept a
    hash reference as an optional second argument. Hash keys
    will be x (where x is the switch name) with key values the
    value of the argument or 1 if no argument is specified.

    Like this:

    getopts('oif:', \%opts); # options as normal. Values in %opts

    I have a feeling that that way is the "most correct" way. That way
    the values being grabbed off the command line options will be scoped
    specifically where you want them to be instead of being globals.

    comments?

    --Errin
    Errin Guest

  6. #6

    Default Re: Opening file($ARGV) with Getopt - failing

    Edward Wijaya wrote: 

    Hello,
     

    getopts( 'f:' ) creates the variable $opt_f and stores the following argument
    'filename' in that variable and *REMOVES* those arguments from ARGV so that
    ARGV is now empty.

     

    Since ARGV is now empty, $f is also empty (undef).

     

    Since ARGV is now empty there is nothing for <> to open and read from.

     


    You should do it like this instead:

    use strict;
    use warnings;

    use Getopt::Std;

    getopts( 'f:', \my %opt );

    open INFILE, '<', $opt{ f } or die "$0 : failed to open input file $opt{f} : $!";

    while ( <INFILE> ) {
    print;
    }

    close INFILE;

    __END__



    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  7. #7

    Default RE: Opening file($ARGV) with Getopt - failing

    Errin Ln wrote: 

    I don't know, but I suspect it's because "our" is a complement to "my". Same
    syntax (no silly qw() business), same lexical scoping, etc.

    You're correct. our() should be used and 'use vars' should be considered
    deprecated.
    Bob Guest

  8. Moderated Post

    Default Re: Opening file($ARGV) with Getopt - failing

    Removed by Administrator
    Wiggins Guest
    Moderated Post

  9. #9

    Default Re: Opening file($ARGV) with Getopt - failing

    On Tue, 28 Sep 2004, Wiggins d Anconia wrote:
     
    > >
    > > That is debatable.[/ref]
    >
    > Please, beginners, recognize the above word, *debatable*!![/ref]

    <aol />

    I'm not forwarding this along as a blanket assertion that 'our' is bad,
    broken, and always to be avoided. None of that is true. Rather, I'm
    using it as an example of how a seemingly innocuous new feature can have
    unexpected & possibly hard to debug consequences "in the wild".

    If you're only writing for yourself on systems that you have fulll
    control over, then this particular example probably isn't a big deal.
    If, on the other hand, you get a job where you have to work with the
    available software, then you may be stuck.

    It is worthwhile to spend a few minutes figuring out what problem a new
    feature solves, reflecting on whether that problem impacts you (chances
    are good that it does, but it might not), and considering whether or not
    using this new construct over older methods introduces new problems (it
    should not, but it might).

    To just blindly accept a suggestion like this without at least a little
    bit of thought is what is called "cargo culting"; it's a bad habit:

    <http://catb.org/~esr/jargon/html/C/cargo-cult-programming.html>
    <http://www.physics.brocku.ca/etc/cargo_cult_science.html>
    <http://en.wikipedia.org/wiki/Cargo_cult>

    That said, here's one article (of several, surely) that contrasts the
    'my' and 'our' functions:

    <http://perlmonks.thepen.com/105446.html>

    Be aware of what's going on here before concluding that 'our' is always
    the one to use. It might be, maybe, but it might not.

    That's all :-)
     
    >
    > This is opinion taken out of context, and stated as a rule rather than a
    > suggestion, which may be a bit over the top.[/ref]

    Maybe so, but I thought it was striking that Jokob Neilsen has written
    similar things about adopting new features in web design. Consider the
    footnote for this essay:

    Normally, I advise against using new Web technologies for the first
    year after they have been introduced. In most cases, using anything
    new is asking for trouble and will alienate users with older browsers.

    Link titles are an exception to the need to wait a year. First, their
    use does not hurt users with browsers that don't display link titles
    [....] Second, a browser that does not understand link titles will
    simply skip them. [....] The only downside is that link titles will
    add approximately 0.1 seconds to the download time for a typical
    Web page over a modem connection. This is a rather harsh penalty,
    but worth paying because of the increased navigation usability for
    those users who do get to see the link titles.

    At the time of this writing, link titles will probably only be seen
    by 25% of the users. Normally, this would be insufficient to employ
    a new Web technology, but since link titles are extremely easy to
    add to your pages and since they do not pose any danger to users
    with older browsers, it makes sense to go ahead and start using link
    titles. [....]

    <http://www.useit.com/alertbox/980111.html>

    Note the way he thinks this through. The base instinct is conservative:
    most new features introduce problems bigger than the one they solve, so
    he avoids them. In this case, however, the problem is broad, the risks
    are slight, and the benefits are large, so he breaks the usual rule.

    That, I think, is the right approach to new features in any language.
     

    Beats me -- is it?

    I don't think there's a blanket rule here, one way or the other. It
    comes down to what your expectations are for your code, whether or not
    it could have a life of its own after you're done with it, etc.

    If nothing else, it might not be bad to start off scripts using new
    features with a

    require 5.6.1;

    (or whatever the first version with 'our' was), with a comment saying
    what construct you're using that demands the require statement.


    But anyway, I'll leave it at that, as this is turning into a long
    discussion with no real right or wrong sides but lots of talk... :-)



    --
    Chris Devers
    Chris Guest

Similar Threads

  1. perl crashing at $image->Read (file=> \*ARGV);
    By Wiggins in forum PERL Beginners
    Replies: 3
    Last Post: September 13th, 03:18 PM
  2. Supspend opening the file after create pdf file from Adobe PDF
    By Ray_Li@adobeforums.com in forum Adobe Acrobat Windows
    Replies: 2
    Last Post: May 20th, 02:55 PM
  3. Acrobat Reader failing repeatedly on same file rp505enu.exe
    By AndreaLDBrandt@adobeforums.com in forum Adobe Acrobat Windows
    Replies: 1
    Last Post: April 30th, 07:35 PM
  4. Bitmaps are displaced when opening FH9 file-I need a test file
    By Delores in forum Macromedia Freehand
    Replies: 2
    Last Post: July 25th, 08:22 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139