Opening file($ARGV) with Getopt - failing

2004-09-28 Thread Edward Wijaya
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__ 
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



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

2004-09-28 Thread Errin Larsen
Hi Edward!


On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
[EMAIL PROTECTED] wrote:
 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;

  Good Start!  Those pragmas above are very helpful!

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

  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;

 getopts('f:');
 
 my  $f = $ARGV[0];
 open ( INFILE, '', $f)
  or die $0 : failed to open input file $f : $!\n;
  
  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: $!;

 close ( INFILE );
 
  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;
}

 while (  )
 {
  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.

 }
 __END__
 
 --
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 http://learn.perl.org/ http://learn.perl.org/first-response
 
 

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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread Errin Larsen
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
[EMAIL PROTECTED] wrote:
 Thanks Errin,
 It works just as you suggested.
 Thanks so much for your thorough
 explanation. Glad that I learnt much from it.
 
 
  Edward, I could write this script two ways.  The first is the way I
  prefer and it doesn't use 'Getopt::Std' at all:
 
 I need to use Getopt, as I will increase
 the number of user given options.
 
 Regards
 Edward WIJAYA
 

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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread Chris Devers
On Tue, 28 Sep 2004, Errin Larsen wrote:

 On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
 [EMAIL PROTECTED] wrote:
 
  use vars qw($f);
 
   The above is good, but is now obsolete. 

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 updateor 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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread Errin Larsen
On Tue, 28 Sep 2004 15:26:08 -0400 (EDT), Chris Devers
[EMAIL PROTECTED] wrote:
 On Tue, 28 Sep 2004, Errin Larsen wrote:
 
  On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
  [EMAIL PROTECTED] wrote:
 
   use vars qw($f);
 
The above is good, but is now obsolete.
 
 That is debatable.
 
 Gather round, and listen to the story of a log handling utility

SNIP

 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
 

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' documentation.  (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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread John W. Krahn
Edward Wijaya wrote:
 Hi,
Hello,
 Why my code below fail to open and
 print the file contents

 when I do:

 perl mycode.pl -f filename


 __BEGIN__
 use strict;
 use warnings;

 use Getopt::Std;
 use vars qw($f);
 getopts('f:');
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.

 my$f = $ARGV[0];
Since @ARGV is now empty, $f is also empty (undef).
 open ( INFILE, '', $f)
 or die $0 : failed to open input file $f : $!\n;
 close ( INFILE );

 while (  )
Since @ARGV is now empty there is nothing for  to open and read from.
 {
 print $_;
 }   __END__
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
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



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

2004-09-28 Thread Bob Showalter
Errin Larsen wrote:
 So, what was the justification for changing 'use vars' to 'our'?

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.

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread Wiggins d Anconia
 On Tue, 28 Sep 2004, Errin Larsen wrote:
 
  On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
  [EMAIL PROTECTED] wrote:
  
   use vars qw($f);
  
The above is good, but is now obsolete. 
 
 That is debatable.


Please, beginners, recognize the above word, *debatable*!!  I disagree
with the suggestion and feel that in many, many cases you will be better
off targeting newer features, especially since many times programs are
not distributed.  Once you get to a point of distribution, *and* someone
requests that you backport your script then make the change, it is just
as easy to go in reverse when necessary, than to deny yourself the use
of a tool that was added for good reason.  I don't expect my opinion to
be right, especially in all situations, but if you read this post then
you *need* to read the whole page that Chris linked to so that you can
see what other's thoughts were on the subject.
 
 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?


Well then to me he is disinclined to use the tool, to each his own,
don't let the door hit you on the ass on the way out is an acceptable
answer, and often should be given more
 
 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.
 

Of course, equating 'my' with 'our/use vars' we all know to be wrong...
don't we.

 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.
 

This is opinion taken out of context, and stated as a rule rather than a
suggestion, which may be a bit over the top.

 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 updateor 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:
 

I disagree completely.  Two words, buffer overflow.  See an M$ bug
list for more If this were the case then we would all be writing in
assembly..

  * 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?
 

Definitely worth knowing about the downsides, but I would push the other
direction, is it worth not using something that benefits to prevent
something that may never happen?

 
 -- 
 Chris Devers
 

http://danconia.org

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




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

2004-09-28 Thread Chris Devers
On Tue, 28 Sep 2004, Wiggins d Anconia wrote:

 On Tue, 28 Sep 2004, Chris Devers wrote:
 
  On Tue, 28 Sep 2004, Errin Larsen wrote:
  
   On Tue, 28 Sep 2004 18:51:12 +0800, Edward Wijaya
   [EMAIL PROTECTED] wrote:
   
use vars qw($f);
   
 The above is good, but is now obsolete. 
  
  That is debatable.
 
 Please, beginners, recognize the above word, *debatable*!! 

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 :-)

  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.
  
 
 This is opinion taken out of context, and stated as a rule rather than a
 suggestion, which may be a bit over the top.

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. 

 Definitely worth knowing about the downsides, but I would push the 
 other direction, is it worth not using something that benefits to 
 prevent something that may never happen?

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

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/