[12547] in Perl-Users-Digest
Perl-Users Digest, Issue: 6146 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Jun 27 18:07:15 1999
Date: Sun, 27 Jun 99 15:00:24 -0700
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 27 Jun 1999 Volume: 8 Number: 6146
Today's topics:
Re: "Slurping" a .jpg file (Abigail)
Re: "Slurping" a .jpg file <mhc@Eng.Sun.COM>
Re: A necessary # in statement (Larry Rosler)
Re: Command line parameters / Wildcard characters / Rec (Abigail)
Re: Command line parameters / Wildcard characters / Rec <tchrist@mox.perl.com>
compare number and string <jonaslar@online.no>
Re: Comparing two associative arrays (Abigail)
Re: dbm and untie error (Anno Siegel)
Re: deleting part of a string (Abigail)
Re: FAQ 2.16: Where can I buy a commercial version of P <cassell@mail.cor.epa.gov>
Re: FAQs and attitudes (was Re: How can I read a whole (Abigail)
Re: FAQs and attitudes (was Re: How can I read a whole <tchrist@mox.perl.com>
Re: faqs, beginner question <cassell@mail.cor.epa.gov>
Re: floor and ceil <kenrose@home.com>
Re: floor and ceil (Larry Rosler)
Re: floor and ceil <tchrist@mox.perl.com>
FMTEYEWTK on shell globbing (was: Command line paramete <tchrist@mox.perl.com>
Re: hello looking for script <cassell@mail.cor.epa.gov>
Special: Digest Administrivia (Last modified: 12 Dec 98 (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 27 Jun 1999 14:14:11 -0500
From: abigail@delanet.com (Abigail)
Subject: Re: "Slurping" a .jpg file
Message-Id: <slrn7nctvk.npo.abigail@alexandra.delanet.com>
Rich Campbell (rcampbel@gbtech.net) wrote on MMCXXV September MCMXCIII in
<URL:news:01bebf6c$26ca06e0$c5dfffcc@upstairs>:
??
?? open(FD, "picture.jpg");
You have a semicolon after the closing paren.
That's wrong.
Abigail
--
perl -wle 'print "Prime" if ("m" x shift) !~ m m^\m?$|^(\m\m+?)\1+$mm'
-----------== Posted via Newsfeeds.Com, Uncensored Usenet News ==----------
http://www.newsfeeds.com The Largest Usenet Servers in the World!
------== Over 73,000 Newsgroups - Including Dedicated Binaries Servers ==-----
------------------------------
Date: 27 Jun 1999 13:29:28 -0700
From: Mike Coffin <mhc@Eng.Sun.COM>
Subject: Re: "Slurping" a .jpg file
Message-Id: <8p61zex8k0n.fsf@Eng.Sun.COM>
"Rich Campbell" <rcampbel@gbtech.net> writes:
>
> I've tried "slurping" the file by:
>
> open(FD, "picture.jpg");
>
> undef $/;
>
> $file = <FD>;
>
> but no go (but it works fine for a .txt file)
>
> --------------
>
> Suggestions (Other than Perlfaq5 - been there)
open(FD, "picture.jpg") or die "cannot open file: $!";
-mike
------------------------------
Date: Sun, 27 Jun 1999 12:44:28 -0700
From: lr@hpl.hp.com (Larry Rosler)
Subject: Re: A necessary # in statement
Message-Id: <MPG.11e01ef2bd8cdfc3989c5a@nntp.hpl.hp.com>
[Posted and a courtesy copy sent.]
In article <37765BB1.B7B8CAA8@uswest.net> on Sun, 27 Jun 1999 10:13:21 -
0700, Ryan Hilton <littledude@uswest.net> says...
> I am fairly new at PERL and I was going over some source
> code that a friend helped me with and I noticed that there
> was a comment in the middle of a statement, my example is
> below.
>
> for ($i=1;$i<=$#files;$i++) {
>
> Why is this comment field used and not marking the rest of
> the line as being commented? and why will it not work if I
> get rid of the comment character in all of the statements
> that contain it?
The Perl grammar recognizes # as syntactic not only for the case you
encountered (last-array-index, which Rick Delaney has explained), but
also these:
m#...# s#...#...# tr#...#...# q#...# qq#...#
And, of course, within quotes:
'...#...' "...#..." <<HERE_DOC
...#...
HERE_DOC
And a deprecated special variable, $#.
Careless writers of syntax-coloring text editors often get these wrong,
as you did.
--
(Just Another Larry) Rosler
Hewlett-Packard Laboratories
http://www.hpl.hp.com/personal/Larry_Rosler/
lr@hpl.hp.com
------------------------------
Date: 27 Jun 1999 15:18:49 -0500
From: abigail@delanet.com (Abigail)
Subject: Re: Command line parameters / Wildcard characters / Recursive directories
Message-Id: <slrn7nd1ot.v72.abigail@alexandra.delanet.com>
Eric Anderson (eman@cc.gatech.edu) wrote on MMCXXVI September MCMXCIII in
<URL:news:37756E51.9A009E51@cc.gatech.edu>:
^^
^^ Now the question is how will the work out under Unix. Since it processes
^^ the wildcard characters before I even get it I won't know what wildcard
^^ string to use with glob on the subdirectories. Any pointers? Thanks for
^^ any help anyone to provide.
Easy. Require that the arguments are quoted. After all, that's the way
find works.
Abigail
--
srand 123456;$-=rand$_--=>@[[$-,$_]=@[[$_,$-]for(reverse+1..(@[=split
//=>"IGrACVGQ\x02GJCWVhP\x02PL\x02jNMP"));print+(map{$_^q^"^}@[),"\n"
-----------== Posted via Newsfeeds.Com, Uncensored Usenet News ==----------
http://www.newsfeeds.com The Largest Usenet Servers in the World!
------== Over 73,000 Newsgroups - Including Dedicated Binaries Servers ==-----
------------------------------
Date: 27 Jun 1999 15:31:19 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: Command line parameters / Wildcard characters / Recursive directories
Message-Id: <37769827@cs.colorado.edu>
[courtesy cc of this posting mailed to cited author]
In comp.lang.perl.misc, abigail@delanet.com writes:
:Easy. Require that the arguments are quoted. After all, that's the way
^^^
:find works.
Well, that's hardly a subjunctive opinion. :-)
--tom
--
There is, however, a strange, musty smell in the air that reminds me of
something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
--Larry Wall in Configure from the perl distribution
------------------------------
Date: Sun, 27 Jun 1999 23:30:33 +0200
From: "Jonas Larsen" <jonaslar@online.no>
Subject: compare number and string
Message-Id: <QGwd3.540$o_1.2948@news1.online.no>
I have got a problem!
How do I compare these to variables?
Like this:
Suppose that the file has size 17 bytes.
$x=34/2;
$y=stat('filename')[7]; ( I think this gives the size of the file)
Main question is:
How do I compare x and y?
Jonas
------------------------------
Date: 27 Jun 1999 15:40:10 -0500
From: abigail@delanet.com (Abigail)
Subject: Re: Comparing two associative arrays
Message-Id: <slrn7nd30t.v72.abigail@alexandra.delanet.com>
Rick Delaney (rick.delaney@home.com) wrote on MMCXXVI September MCMXCIII
in <URL:news:377668B8.EB9FDA96@home.com>:
:: [posted & mailed]
::
:: Larry Rosler wrote:
:: >
:: > I'm not convinced by this argument. Suppose, for example, that the two
:: > hashes were initialized (by keys()) to different sizes and populated in
:: > different sequences. Where is the guarantee that the hashing function
:: > will cause retrieval in the same order for each hash?
::
:: I'm not convinced either but I've not been able to produce a
:: counter-example.
::
:: > Certainly nothing like that is documented, in any case. So relying on
:: > it fatuous, at best.
::
:: True, but if Bart is correct and this is reliable then the documentation
:: should be fixed. If this is a feature then let's see it documented.
However, Bart is wrong, and Larry is right.
#!/opt/perl/bin/perl -w
use strict;
my (%hash1, %hash2);
keys %hash1 = 20000;
foreach ('aa' .. 'zz') {
$hash1 {$_} = 1;
$hash2 {$_} = 1;
}
print "Different\n" if "@{[%hash1]}" ne "@{[%hash2]}";
__END__
This will print "Different".
Of course, it could also easily fail if there are keys and values that
contain $" as a substring. Deja will show threads which shows that
"@array1" eq "@array2" is the wrong way to test whether 2 arrays have
the same content.
Abigail
--
srand 123456;$-=rand$_--=>@[[$-,$_]=@[[$_,$-]for(reverse+1..(@[=split
//=>"IGrACVGQ\x02GJCWVhP\x02PL\x02jNMP"));print+(map{$_^q^"^}@[),"\n"
-----------== Posted via Newsfeeds.Com, Uncensored Usenet News ==----------
http://www.newsfeeds.com The Largest Usenet Servers in the World!
------== Over 73,000 Newsgroups - Including Dedicated Binaries Servers ==-----
------------------------------
Date: 27 Jun 1999 19:03:24 -0000
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: dbm and untie error
Message-Id: <7l5shs$tde$1@lublin.zrz.tu-berlin.de>
Chris Chandler <cchandleNO@SPAMucla.edu> wrote in comp.lang.perl.misc:
>I am trying to migrate an application from an old Digital
>Unix machine which blew up to a Linux Redhat 5.2. Since the old machine
>is dead as a doornail I'm not sure which version of Perl it had.
>
>Anyway, the app works ok except for this little section:
>
>--
>94 while (($res = dbmopen (%s, "$dbdir/services", 0400)) == 0 &&
>95 $! == $EAGAIN) {} ;
>96 %services = %s ;
>97 dbmclose (%s) ;
>--
>
>
>(which is actually repeated more or less in several parts of the code)
>
>When the file runs I get this error:
>
>"untie attempted while 1 inner references
>still exist at ./dumpservices line 97"
>
>I suspect my problem is related to either the version of Perl that I'm
>running or, the differences in version/type of DB between the old
>machine and the new Linux (well, Red Hat 5.2) machine I'm porting it to.
The dbmopen function is really only kept for compatibility, you should
probably move on to tie. The following works for me, using a dbm
file I happen to have around:
#!/usr/bin/perl -w
use DB_File;
$EAGAIN = 11; # This should, of course, be done in a portable way
while ( $o = $tie( %s, 'DB_File', 'English/count.db', O_RDONLY) == 0 and
$! == $EAGAIN ) {};
die "Can't tie to database\n" unless defined $o;
%services = %s;
untie( %s);
print scalar keys %services, "\n"; # Just to show that it worked.
If you have a different kind of Database (NDBM, GDBM, SDBM), use that
instead.
Anno
------------------------------
Date: 27 Jun 1999 15:08:00 -0500
From: abigail@delanet.com (Abigail)
Subject: Re: deleting part of a string
Message-Id: <slrn7nd12u.v72.abigail@alexandra.delanet.com>
Ronald J Kimball (rjk@linguist.dartmouth.edu) wrote on MMCXXVI September
MCMXCIII in <URL:news:1du1aaa.15wlrgvo8nijiN@p11.tc2.metro.ma.tiac.com>:
() Abigail <abigail@delanet.com> wrote:
()
() > ** Longer to type, yes....
() > ** but beside to mererly show another way, I also
() > ** blindly assumed that he wanted to extract string
() > ** contains file path (or URL). And that's what
() > ** ^
() > ** |
() > ** +--------------------+
() > ** the module does. Talking about portable, the|
() > ** module is platform independent. |
() > |
() > The problem is that the code as given above, doe| *NOT* remove everything
() > from the last slash onwards. What it exactly doe| depends on the platform.
() > And URL separators don't change when moving from|platform to platform.
() > |
() > The module is platform independent if you know w|at you are doing, it'll
() > break your code if used unwisely. Using File::Ba|ename for dealing with
() > URLs is unwise. |
() |
() This is the first mention of URLs in this thread. |How do you know that
| |
+-------------------+
() the data in question ('computers/hardware/monitors/sony') is a URL?
() Note: There's not even a protocol specifier.
()
() Perhaps the data is a local file path, in which case File::Basename *is*
() an appropriate solution.
Perhaps, perhaps. My point is that you do *NOT* know what the data is.
The original question mentioned neither files nor URLs.
Abigail
--
perl -wle 'print "Prime" if ("m" x shift) !~ m m^\m?$|^(\m\m+?)\1+$mm'
-----------== Posted via Newsfeeds.Com, Uncensored Usenet News ==----------
http://www.newsfeeds.com The Largest Usenet Servers in the World!
------== Over 73,000 Newsgroups - Including Dedicated Binaries Servers ==-----
------------------------------
Date: Sun, 27 Jun 1999 14:53:57 -0700
From: David Cassell <cassell@mail.cor.epa.gov>
Subject: Re: FAQ 2.16: Where can I buy a commercial version of Perl?
Message-Id: <37769D75.2A1BA9EA@mail.cor.epa.gov>
Philip 'Yes, that's my address' Newton wrote:
>
> On 25 Jun 1999 13:03:56 -0700, Tom Christiansen
> <perlfaq-suggestions@perl.com> wrote:
>
> > comp.lang.perl.* newsgroups and several of the mailing lists
> > provide free answers to your questions in near real-time.
>
> This *does* seem to be what a lot of people expect, doesn't it?
> Especially the "free" ("without having to think or--shudder--read the
> docs") and "near real-time" ("if I don't get an answer in two hours,
> I'll post again; maybe they didn't see it" or "urgent, need this
> program by Friday").
But this quote isn't the real problem, since it's the people
who either can't or won't read the FAQ who seem to be the
problems. So they never see these lines. But if you have a
change you want to see, go ahead and submit it to
perlfaq-suggestions. After all, it's not like Tom is going to
bite your head off or anything...
I could see that last line being changed to:
> > provide free answers to your questions in near real-time
assuming you follow the group guidelines.
David
--
David Cassell, OAO cassell@mail.cor.epa.gov
Senior computing specialist
mathematical statistician
------------------------------
Date: 27 Jun 1999 15:10:28 -0500
From: abigail@delanet.com (Abigail)
Subject: Re: FAQs and attitudes (was Re: How can I read a whole file in one go ?)
Message-Id: <slrn7nd197.v72.abigail@alexandra.delanet.com>
Larry Rosler (lr@hpl.hp.com) wrote on MMCXXVI September MCMXCIII in
<URL:news:MPG.11df207e5d066137989c52@nntp.hpl.hp.com>:
-- In article <slrn7nas3k.npo.abigail@alexandra.delanet.com> on 26 Jun 1999
-- 19:29:53 -0500, Abigail <abigail@delanet.com> says...
-- ...
-- > $ cd ~/Src/perl5.005_57/pod
-- > $ cat *.pod | grep -ci 'billtax'
-- > 1
-- > $ cat *.pod | grep -ci 'prisoner of bill'
-- > 1
-- > $
--
-- I think Randal owes you two Useless Use of Cat Awards for that. Or
-- perhaps only one. :-)
Oh really? How would you do this without cat then?
(Hint: grep -ci 'billtax' *.pod doesn't give the same output, and quickly
glancing over the man page of grep didn't enlighten me with a command line
option that did.)
Abigail
--
%0=map{reverse+chop,$_}ABC,ACB,BAC,BCA,CAB,CBA;$_=shift().AC;1while+s/(\d+)((.)
(.))/($0=$1-1)?"$0$3$0{$2}1$2$0$0{$2}$4":"$3 => $4\n"/xeg;print#Towers of Hanoi
-----------== Posted via Newsfeeds.Com, Uncensored Usenet News ==----------
http://www.newsfeeds.com The Largest Usenet Servers in the World!
------== Over 73,000 Newsgroups - Including Dedicated Binaries Servers ==-----
------------------------------
Date: 27 Jun 1999 15:28:53 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: FAQs and attitudes (was Re: How can I read a whole file in one go ?)
Message-Id: <37769795@cs.colorado.edu>
[courtesy cc of this posting mailed to cited author]
In comp.lang.perl.misc, abigail@delanet.com writes:
:-- I think Randal owes you two Useless Use of Cat Awards for that. Or
:-- perhaps only one. :-)
I love how has taken up the burden of giving out the awards I long
ago invented. That way I don't have to slum in c.u.shell so much. :-)
:Oh really? How would you do this without cat then?
:
:(Hint: grep -ci 'billtax' *.pod doesn't give the same output, and quickly
:glancing over the man page of grep didn't enlighten me with a command line
:option that did.)
The `-h' option, which some but surely not all greps support.
--tom
--
"Most of what I've learned over the years has come from signatures."
--Larry Wall
------------------------------
Date: Sun, 27 Jun 1999 13:26:37 -0700
From: David Cassell <cassell@mail.cor.epa.gov>
Subject: Re: faqs, beginner question
Message-Id: <377688FD.11580E8@mail.cor.epa.gov>
Jonathan Stowe wrote:
>
> On Sat, 26 Jun 1999 03:15:57 GMT Jon Bell wrote:
> > David Cassell <cassell@mail.cor.epa.gov> wrote:
> >>
> >>In fact, Perl has snitched good things from a slew of different
> >>programming languages and tools.
> >
> > In other words, Perl is a "mongrel". :-)
> >
> > (Not that there's anything *wrong* with that...
>
> Well most of us would prefer to describe it as 'selective breeding'.
I prefer the ag term 'hybrid vigor'. :-)
David
--
David Cassell, OAO cassell@mail.cor.epa.gov
Senior computing specialist
mathematical statistician
------------------------------
Date: Sun, 27 Jun 1999 19:03:44 GMT
From: Kenneth Rose <kenrose@home.com>
Subject: Re: floor and ceil
Message-Id: <37767578.B69DEF7B@home.com>
Found it!
use POSIX;
$ceil = ceil(3.5); # 4
$floor = floor(3.5); # 3
Thank you for your sarcasm Rick.
/<en
Kenneth Rose wrote:
>
> Hi everyone,
>
> Just wondering if such functions exist: floor and ceil. Floor would
> return the greatest integer less than or equal to the argument. Ceil
> would return the least integer greater than or equal to the argument.
>
> Thanks all!
>
> /<en
------------------------------
Date: Sun, 27 Jun 1999 12:57:38 -0700
From: lr@hpl.hp.com (Larry Rosler)
Subject: Re: floor and ceil
Message-Id: <MPG.11e022055a02f84d989c5b@nntp.hpl.hp.com>
[Posted and a courtesy copy sent.]
In article <37766DBB.316C14F0@home.com> on Sun, 27 Jun 1999 18:30:43
GMT, Kenneth Rose <kenrose@home.com> says...
> Just wondering if such functions exist: floor and ceil. Floor would
> return the greatest integer less than or equal to the argument. Ceil
> would return the least integer greater than or equal to the argument.
perlfaq4: "Does Perl have a round() function? What about ceil() and
floor()? Trig functions?"
--
(Just Another Larry) Rosler
Hewlett-Packard Laboratories
http://www.hpl.hp.com/personal/Larry_Rosler/
lr@hpl.hp.com
------------------------------
Date: 27 Jun 1999 15:17:12 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: floor and ceil
Message-Id: <377694d8@cs.colorado.edu>
[courtesy cc of this posting mailed to cited author]
In comp.lang.perl.misc,
Kenneth Rose <kenrose@home.com> writes:
:Just wondering if such functions exist: floor and ceil. Floor would
:return the greatest integer less than or equal to the argument. Ceil
:would return the least integer greater than or equal to the argument.
Might one inquire as to which part of the standard answer to this standard
question as included in the standard perlfaq4 manpage that ships standard
with every perl distribution did you find particularly opaque?
--tom
Does Perl have a round() function? What about ceil() and floor()?
Trig functions?
Remember that int() merely truncates toward 0. For rounding to a
certain number of digits, sprintf() or printf() is usually the
easiest route.
printf("%.3f", 3.1415926535); # prints 3.142
The POSIX module (part of the standard perl distribution)
implements ceil(), floor(), and a number of other mathematical
and trigonometric functions.
use POSIX;
$ceil = ceil(3.5); # 4
$floor = floor(3.5); # 3
In 5.000 to 5.003 Perls, trigonometry was done in the
Math::Complex module. With 5.004, the Math::Trig module (part of
the standard perl distribution) implements the trigonometric
functions. Internally it uses the Math::Complex module and some
functions can break out from the real axis into the complex
plane, for example the inverse sine of 2.
Rounding in financial applications can have serious
implications, and the rounding method used should be specified
precisely. In these cases, it probably pays not to trust
whichever system rounding is being used by Perl, but to instead
implement the rounding function you need yourself.
To see why, notice how you'll still have an issue on half-way-
point alternation:
for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}
0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
0.8 0.8 0.9 0.9 1.0 1.0
Don't blame Perl. It's the same as in C. IEEE says we have to do
this. Perl numbers whose absolute values are integers under
2**31 (on 32 bit machines) will work pretty much like
mathematical integers. Other numbers are not guaranteed.
--
Someone who truly understands Unix not only understands why "rm *"
screws you, but understands why IT HAS TO BE THAT WAY.
------------------------------
Date: 27 Jun 1999 15:13:22 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: FMTEYEWTK on shell globbing (was: Command line parameters / Wildcard characters / Recursive directories)
Message-Id: <377693f2@cs.colorado.edu>
[courtesy cc of this posting mailed to cited author]
Thank you for clarifying. Thank you for trying harder (you still
need a spell-checker, though, and a grammar-checker.) Thank you for
including notification of the expedited carbon copy that you maild me.
But did you know your newsreader is so broken that it actually had the
audacity to *wrap* the subject line? My goodness, but I can't believe
how fundamentally stupid consumerware is.
But you tried hard and were very courteous, so I'll try hard to give
you my very best answer. I hope it helps.
In comp.lang.perl.misc, Eric Anderson <eman@cc.gatech.edu> writes:
:The basic issue that I am trying to figure out is how to get around
:problems I am having with perl's interaction with various some shells.
:Specifically I am trying to figure out if there is a way to get around
:the automatic wildcard expansion done by some UNIX shells.
Keep in mind that this is entirely a shell question only, and that is
in no way a Perl question. Whatsoever answer I give here regarding
calling Perl with literal arguments will also hold eually true for the
invocation of any other possible program.
:Other command line utilities such as 'rm' can apply a given wildcard
:string recursively down directories (such as rm -rf *.html would delete
:all 'html' files in the current directory and every subdirectory of the
:current directory).
No, that's not the way it works, actually. Given traditional shell
semantics, when you supply the shell with an rm(1) command with an
argument of "*.html"--without the quotes--the shell and not rm(1) will
look in the current directory for files whose names end in ".html"
and which do not begin with ".", and proceed to unlink them recursively.
What does it mean to "delete a file recursively"? It means that if
that file contains other files, to wit, is a directory, then the files
contained below will be unlinked as well. Remember that a directory *is*
merely a type of file. However, the wildcard a.k.a glob pattern you
specified is relevant to the invoking shell alone, not to the program.
By the time that the program is called, the pattern has been expanded.
This is very important as I shall explain below.
In fact, the unlink(2) system call, which the the rm(1) program invokes,
provides no pattern-based calling convention, any more than does the
link(2) or open(2) system call. If you did happen to have a directory
whose name ended in ".html" and which did not begin with a dot, then
*everything* in that directory would be unlinked.
:This would believe me to think that there is some
:way around this problem that I am having with these unix shells.
Again, the problem lies not in the shells, Eric, but in understanding
of how they work.
I present now a variety of approaches to by-passing the shell's
expansion in order to pass a literal to a program. I'll be using by
way of demonstration rather than the perilous rm(1), the hypothetical
frobnitz(1) program instead.
A1) You can quote the argument:
$ frobnitz "*.html"
$ frobnitz '*.html'
A2) You can escape the argument:
$ frobnitz \*.html
A3) You can, on some shells, disable globbing temporarily:
% set noglob; frobnitz *.html; unset noglob
A4) In fact, if it were your own csh or tcsh style shell, you could
create an alias that did this automagically
alias 'frobnitz' 'set noglob;frobnitz \!*`; unset noglob'
But this can be problematic: if the thwap the frobbing program
in the middle of its run with a ^C, then you won't restore
your shell to its proper globbiness.
Now, you seemed to think that recursive programs such as rm(1), cp(1),
and the like all "knew" to apply their glob expression to subdirectories.
This is simply not the case. Instead, applying the toolkit approach of
interchangeable parts, we use the find(1) command to locate candidates.
You'll notice that find(1) is one of those scant few programs that
actually expect as thier argument an unqualified glob. This means we'll
have to quote that argument as explained above.
Again, we have several possible approaches:
B1) Invoke find(1) in backticks, whose output you'll frob:
% frobnitz `find . -name '*.html'`
B2) Avoid the chance of exceeding the maximum buffer size on argument
lists (historically, NCARGS in <sys/param.h> by frobbing the output
interatively through a series of calls to the program:
% find . -name \*.html -exec frobnitz {} \;
(or of course also)
% find . -name '*.html' -exec frobnitz {} ';'
B3) Avoid the overhead of so many execs by bundling up sets of
output.
% find . -name '*.html' -print | xargs frobnitz
B4) In case you have a file named "ohmy\ngoodness.html" (or even
("die\netc/passwd\ngotcha.html"; be very afraid!), this had really
best be:
% find . -name '*.html' -print0 | xargs -0 frobnitz
B5) On some shells, the find-style recursion may be built in. For
example, zsh(1) has this remarkably useful feature:
% frobnitz **/*.html
:If there is not then that is fine. I will either use other characters
:to indicate wildcard characters or require the use of quotes.
Good.
:But if it is possible, then that would be nicer because that would allow
:my program to work in a more consistant style that the other command
:line utilities have.
Oh my. I'm afraid you've just generated another unparsable sentence.
Sigh. The spelling error aside (the originating verb was of course
"consistere" not "*consistare"), I can't tell whether you mean "than"
where you have "that", or whether you omitted the remainder of the entire
clause that you.
See what I mean? :-)
:Athough using another shell might be a solution, it is not a solution
:that I can use because the requirements for this program is to work
:under Win32 (and I would perfer it to work under UNIX also). I cannot
Someone seems to have perforated your perfervid prose with bugs.
And since so many misspellings are actually abstruse but valid terms,
I'm afraid that only a perfunctory spell-checker would be of any avail.
:specify the user to use a different shell so I am forced to deal with
:this issue in my program.
Microsoft does not supply its victims with usable shells. Period.
(That doesn't mean none are available; merely that the Lords of Redmond
do not deign to supply the pitiable masses with such.) You seem to
feel that you cannot expect your users to use a usable shell. This is
problematic at best.
Here's an idea. Why don't you do this: supply an auxiliary program that
users bereft of a properly working shell might use in conjunction with
your original program, that the normal users not suffer?
For example, suppose we posit the existence of a glob(1) program.
I'll quote the argument just in case.
% frobnitz `glob '*.html'`
Now those without working shells can still glob. You might find it
interesting to learn that truly ancient Unix systems (up through V6, I
believe) were up the same creek as most Prisoners of Bill using unenriched
systems today are, save that those early Unix users happened to have a
paddle with them up that creek.
Steve Johnson and Brian Kernighan write about this in passing
in a document found on Dennis Ritchie's home page:
http://cm.bell-labs.com/cm/cs/who/dmr/bintro.html
Indeed, there were never very many B programs on early Unix. The
compiler itself was written in B, and a few of the utilities, for
example the first /etc/glob, which expanded wild-card characters for
the shell. This is because no compiler to machine code for the PDP-7
or PDP-11 was ever built; the Unix B compilers produced interpreted,
threaded code that wasn't efficient enough to write a whole system in.
You can find a simple implementation of a glob(1) program in the
Unix Reconstruction Project at:
http://language.perl.com/ppt/src/glob/index.html
I personally use the tfiles(1) program for this kind of thing. It
is a filter that produces only regular files (see below about directories)
that won't jam your line printer. That way you don't have to build
that kind of thing into every possible program. For example:
% vi `tfiles /tmp/*`
% vi `tfiles *`
% vi `tfiles`
Here's a simple implementation:
#!/usr/bin/perl -l
# tfiles - list files that are plain text files
@ARGV = glob("*") unless @ARGV;
for (@ARGV) {
print if -f && -T;
}
Although it might be nicer go the "read stdin for a list
of names" route you can can say
% vi `command that makes file list | tfiles`
Which could be implemented like this:
#!/usr/bin/perl -l
# itfiles - gets list from stdin, maybe
if ( ($ARGV[0] eq '-i' || @ARGV == 0) && !-t STDIN) {
shift;
while (<STDIN>) {
chomp;
push @ARGV, $_;
}
}
elsif (@ARGV == 0) { # but stdin isatty, so read it not!
@ARGV = glob("*");
}
for (@ARGV) {
print if -f && -T;
}
Or even a recursive version, like this:
#!/usr/bin/perl
# rtfiles - recursive tfiles
use File::Find;
*name = *File::Find::name; # can *too* import it!
@ARGV = ('.') unless @ARGV;
sub wanted { print "$name\n" if -f && -T }
find(\&wanted, @ARGV);
:It would seem to me with perl's slant towards text processing that
:someone would have had to deal with this issue before and that is why
:I posted hoping that a nice solution already existed.
I feel it does, as you can see in the examples I've provided above.
It's not strictly clear to me that you are writing a program that
should take an unevaluated glob as one of its command line arguments.
Perhaps you need to spend more time becoming more intimate with the
find(1) program.
:If that is not the case then I will simply use one of the alternatives
:that I described above. It may not be as consistant with the style of
:other command line utilities as I would like but it is a solution and
:in my opinion much better than asking the user to switch the shell they
:use to run a single program.
Expecting consistent behaviour is certainly desirable. I share your goal.
It is, however, inherently unattainable, and it's hardly Perl's fault.
It's Microsoft's fault for being idiots who can't design systems software.
As I've alluded to earlier, there's no hope of that for those suffering
under the grinding heel of Bill's boot.
Up to this point, I have only explained what you should when confronted
with the issue. I have not explained why the situation even arises. I
shall now endeavour to do so.
Imagine you have a file whose actual name is, for example, "Death*Star".
That's a 10-byte string, and the quotes aren't part of it. How do you
specify that file in a consistent fashion? Imagine a user trying to
unlink that file:
% rm Death*Star
By pure happenstance, this would work -- for certain highly suspect values
of "work", that is. You see, the glob would be expanded by the shell
to "Death*Star", and the program would be executed using a call like
execlp("rm", "Death*Star", 0); /* that's C code */
But now imagine that in this directory were also a file name
"DeathOfAStar". Now the program would get run with argument more like so:
execlp("rm", "Death*Star", "DeathOfAStar", 0); /* that's C code */
Well, that's certainly a problem! The standard solution, as outlined
above, is one of these approaches:
% rm 'Death*Star'
% rm "Death*Star"
% rm Death\*Star
Suppose the rm(1) program were to gratuitously sniff out wildcards
and glob your arguments behind your back. You would not be able to
differentiate these. Life would suck.
Welcome to CP/M and its nearly equally cretinous descendents, all of
whom seem to have inherited this complete botch of sane system design.
Down that road lies abomination. In this particular pit of hell,
programmers have been forced to build their own idio(t)syncratic wildcard
expansion algorithms into each and every program. This has historically
led to infuriatingly inconsistent behaviour from one program to the next.
Unless one were to require that each developer use an identical library
interface for argument handling, disparity of implementation will ensue.
Of course, we know that requiring programmers to do anything is a doomed
enterprise. That's one of the reason why the right place for this code
is in no application program whatsoever, but rather in the supervising
shell instead.
But there are other reasons. Imagine now that you had a file named
"Death*Star" but which were now twelve bytes long. Yes, this time
I'm including the quotes as part of the name. If the program always
assumes that the file arguments it receives are literal filenames, there's
no problem. If it does not, then it's in big trouble. It is going to
strip the quotes and then do the glob, and get nothing. Oh, you say,
you'll have to pass the filename in quoted in the first place, like
% rm '"Death*Star"'
Lovely. Let's build on this. Programs often call on other programs
to do part of the work for them. If they want to pass a filename to that
program, it's not enough to just call
execlp("frobnitz", "Death*Star", 0); /* that's C code */
Oh no. Instead you have to carefully look for quotes and wildcards, and
to unambiguously quote the quotes and wildcards, as in some hypothetical
call that would probably look something like this:
runthis("frobnitz \"\"Death*Star\"\""); /* that's C code */
Of course, now the receiving program gets to undo all this.
It is easy to see why, even were an unambiguous quoting, globbing, and
dequoting and deglobbing system theoretically possible, it would still
pose such a horrendously convoluted and error-prone coding nightmare that
its inventor should surely have been fired--and preferably by a firing
squad--long before this Horror Out of Redmouth saw the light of day.
But it was not so, and we've lost his name, so we can't practice the
retroactive abortion on the individual who so patently merits it.
Instead, all Prisoners of Bill, be they willing or unwilling, are
universally consigned to a programming hell of gibbering idiocy because
those clumsy programmers who first blundered through the code to create
this freak of nature ignored the well-establish lessons that those of
us fortunately enough to be living in the comparative heaven of advanced
systems like Unix had many years previous to this already realized.
To this day, Microsoft has failed to provide its programmers with a
reasonable way to call a program without the unintentional side-effects of
obsequious argument mutilation. You see, it only provides the equivalent
of the horrific runthis(3) function above, not something more akin
to execlp(3). As I remarked somewhat snarkily in the Perl Cookbook
("the Ram Book"), about a slightly different matter:
``This legacy of the old CP/M [...] has been a source of frustration
and despair to programmers for decades now. And there's no end
in sight. Because DOS is compatible with CP/M file formats,
Windows with DOS, and NT with Windows, the transgressions of the
fathers have truly been visited unto the children of the fourth
generation.''
I sincerely hope that this missive adequately clarifies this matter for
you, and perhaps several other matters to boot.
--tom "wondering who has really managed to read this far" christiansen
--
Someone who truly understands Unix not only understands why "rm *"
screws you, but understands why IT HAS TO BE THAT WAY.
------------------------------
Date: Sun, 27 Jun 1999 13:59:08 -0700
From: David Cassell <cassell@mail.cor.epa.gov>
Subject: Re: hello looking for script
Message-Id: <3776909C.CC867272@mail.cor.epa.gov>
Jonathan Stowe wrote:
>
> I think that is actually the point - the WebTV *is* extremely limited
> and some of its slightly more clever users have struck upon the
> possibility that some of its shortcomings might be overcome by using
> programs under the CGI on some webserver to supply this lack. Of course
> some of these requirements are plain ridiculous - remember the 'telnet
> as a CGI' madman ? - but they will try (and are often trying too :)
> and, perhaps due to some mindset peculiar to the WebTV user, get a
> bit funny when we try to disabuse them of some of the strange notions
> they have acquired ...
>From private e-mail with this particular poster [not telnet boy
from Nebraska, but the current poster], I learned that the intent
was to run the program from a web server which is acting as some
manner of proxy for the WebTV [I don't know enough about WebTV
to be less vague about it]. But the capabilities and allowed
functionality of such a server are anyone's guess.
Slogan for Nancy Reagan's new campaign against WebTV:
"Just say 'huh?'"
David
--
David Cassell, OAO cassell@mail.cor.epa.gov
Senior computing specialist
mathematical statistician
------------------------------
Date: 12 Dec 98 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Special: Digest Administrivia (Last modified: 12 Dec 98)
Message-Id: <null>
Administrivia:
Well, after 6 months, here's the answer to the quiz: what do we do about
comp.lang.perl.moderated. Answer: nothing.
]From: Russ Allbery <rra@stanford.edu>
]Date: 21 Sep 1998 19:53:43 -0700
]Subject: comp.lang.perl.moderated available via e-mail
]
]It is possible to subscribe to comp.lang.perl.moderated as a mailing list.
]To do so, send mail to majordomo@eyrie.org with "subscribe clpm" in the
]body. Majordomo will then send you instructions on how to confirm your
]subscription. This is provided as a general service for those people who
]cannot receive the newsgroup for whatever reason or who just prefer to
]receive messages via e-mail.
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.misc (and this Digest), send your
article to perl-users@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V8 Issue 6146
**************************************