home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
answers
/
perl-faq
/
part4
< prev
next >
Wrap
Text File
|
1993-10-02
|
13KB
|
389 lines
Newsgroups: comp.lang.perl,news.answers
Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!spool.mu.edu!howland.reston.ans.net!pipex!uunet!boulder!wraeththu.cs.colorado.edu!tchrist
From: Tom Christiansen <tchrist@cs.Colorado.EDU>
Subject: Perl Frequently Asked Questions, part 4 of 4
Message-ID: <CE9Brq.29B@Colorado.EDU>
Followup-To: comp.lang.perl
Originator: tchrist@wraeththu.cs.colorado.edu
Sender: news@Colorado.EDU (USENET News System)
Organization: University of Colorado at Boulder
Date: Sat, 2 Oct 1993 06:38:13 GMT
Approved: news-answers-request@MIT.Edu
Expires: Wed, 1 Dec 1993 12:00:00 GMT
Lines: 373
Xref: senator-bedfellow.mit.edu comp.lang.perl:20585 news.answers:13123
Archive-name: perl-faq/part4
Version: $Id: perl-tech2,v 1.1 93/10/02 00:27:03 tchrist Exp Locker: tchrist $
This posting contains answers to the following technical questions
regarding Perl:
2.29) Why can't my perl program read from STDIN after I gave it ^D (EOF) ?
2.30) Do I always/never have to quote my strings or use semicolons?
2.31) How can I translate tildes in a filename?
2.32) How can I convert my shell script to Perl?
2.33) What is variable suicide and how can I prevent it?
2.34) Can I use Perl regular expressions to match balanced text?
2.35) Can I use Perl to run a telnet or ftp session?
2.36) What does "Malformed command links" mean?
2.37) How can I set up a footer format to be used with write()?
2.38) Why does my Perl program keep growing in size?
2.39) Can I do RPC in Perl?
2.40) What's the difference between delete and undef with %tables?
2.41) How do I do a "tail -f" in Perl?
2.29) Why can't my perl program read from STDIN after I gave it ^D (EOF) ?
Because some stdio's set error and eof flags that need clearing.
Try keeping around the seekpointer and go there, like this:
$where = tell(LOG);
seek(LOG, $where, 0);
If that doesn't work, try seeking to a different part of the file and
then back. If that doesn't work, try seeking to a different part of
the file, reading something, and then seeking back. If that doesn't
work, give up on your stdio package and use sysread. You can't call
stdio's clearerr() from Perl, so if you get EINTR from a signal
handler, you're out of luck. Best to just use sysread() from the
start for the tty.
2.30) Do I always/never have to quote my strings or use semicolons?
You don't have to quote strings that can't mean anything else
in the language, like identifiers with any upper-case letters
in them. Therefore, it's fine to do this:
$SIG{INT} = Timeout_Routine;
or
@Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun);
but you can't get away with this:
$foo{while} = until;
in place of
$foo{'while'} = 'until';
The requirements on semicolons have been increasingly relaxed. You no
longer need one at the end of a block, but stylistically, you're
better to use them if you don't put the curly brace on the same line:
for (1..10) { print }
is ok, as is
@nlist = sort { $a <=> $b } @olist;
but you probably shouldn't do this:
for ($i = 0; $i < @a; $i++) {
print "i is $i\n" # <-- oops!
}
because you might want to add lines later, and anyway,
it looks funny. :-)
2.31) How can I translate tildes in a filename?
Perl doesn't expand tildes -- the shell (ok, some shells) do.
The classic request is to be able to do something like:
open(FILE, "~/dir1/file1");
open(FILE, "~tchrist/dir1/file1");
which doesn't work. (And you don't know it, because you
did a system call without an "|| die" clause! :-)
If you *know* you're on a system with the csh, and you *know*
that Larry hasn't internalized file globbing, then you could
get away with
$filename = <~tchrist/dir1/file1>;
but that's pretty iffy.
A better way is to do the translation yourself, as in:
$filename =~ s#^~(\w+)(/.*)?$#(getpwnam($1))[7].$2#e;
More robust and efficient versions that checked for error conditions,
handed simple ~/blah notation, and cached lookups are all reasonable
enhancements.
2.32) How can I convert my shell script to Perl?
Larry's standard answer for this is to send your script to me (Tom
Christiansen) with appropriate supplications and offerings. :-(
That's because there's no automatic machine translator. Even if you
were, you wouldn't gain a lot, as most of the external programs would
still get called. It's the same problem as blind translation into C:
you're still apt to be bogged down by exec()s. You have to analyze
the dataflow and algorithm and rethink it for optimal speedup. It's
not uncommon to see one, two, or even three orders of magnitude of
speed difference between the brute-force and the recoded approaches.
2.33) What is variable suicide and how can I prevent it?
Variable suicide is a nasty sideeffect of dynamic scoping and
the way variables are passed by reference. If you say
$x = 17;
&munge($x);
sub munge {
local($x);
local($myvar) = $_[0];
...
}
Then you have just clubbered $_[0]! Why this is occurring
is pretty heavy wizardry: the reference to $x stored in
$_[0] was temporarily occluded by the previous local($x)
statement (which, you're recall, occurs at run-time, not
compile-time). The work around is simple, however: declare
your formal parameters first:
sub munge {
local($myvar) = $_[0];
local($x);
...
}
That doesn't help you if you're going to be trying to access
@_ directly after the local()s. In this case, careful use
of the package facility is your only recourse.
Another manifestation of this problem occurs due to the
magical nature of the index variable in a foreach() loop.
@num = 0 .. 4;
print "num begin @num\n";
foreach $m (@num) { &ug }
print "num finish @num\n";
sub ug {
local($m) = 42;
print "m=$m $num[0],$num[1],$num[2],$num[3]\n";
}
Which prints out the mysterious:
num begin 0 1 2 3 4
m=42 42,1,2,3
m=42 0,42,2,3
m=42 0,1,42,3
m=42 0,1,2,42
m=42 0,1,2,3
num finish 0 1 2 3 4
What's happening here is that $m is an alias for each
element of @num. Inside &ug, you temporarily change
$m. Well, that means that you've also temporarily
changed whatever $m is an alias to!! The only workaround
is to be careful with global variables, using packages,
and/or just be aware of this potential in foreach() loops.
The perl5 static autos via "my" will not have this problem.
2.34) Can I use Perl regular expressions to match balanced text?
No, or at least, not by the themselves.
Regexps just aren't powerful enough. Although Perl's patterns aren't
strictly regular because they do backtracking (the \1 notation), you
still can't do it. You need to employ auxiliary logic. A simple
approach would involve keeping a bit of state around, something
vaguely like this (although we don't handle patterns on the same line):
while(<>) {
if (/pat1/) {
if ($inpat++ > 0) { warn "already saw pat1" }
redo;
}
if (/pat2/) {
if (--$inpat < 0) { warn "never saw pat1" }
redo;
}
}
A rather more elaborate subroutine to pull out balanced and possibly
nested single chars, like ` and ', { and }, or ( and ) can be found
on convex.com in /pub/perl/scripts/pull_quotes.
2.35) Can I use Perl to run a telnet or ftp session?
Sure, you can connect directly to them using sockets, or you can run a
session on a pty. In either case, Randal's chat2 package, which is
distributed with the perl source, will come in handly. It address
much the same problem space as Don Libes's expect package does. Two
examples of using managing an ftp session using chat2 can be found on
convex.com in /pub/perl/scripts/ftp-chat2.shar .
Caveat lector: chat2 is documented only by example, may not run on
System V systems, and is subtly machine dependent both in its ideas
of networking and in pseudottys.
2.36) What does "Malformed command links" mean?
This is a bug in 4.035. While in general it's merely a cosmetic
problem, it often comanifests with a highly undesirable coredumping
problem. Programs known to be affected by the fatal coredump include
plum and pcops. Since perl5 is pretty much a total rewrite, we can
count on it being fixed then, but if anyone tracks down the coredump
problem before then, a significant portion of the Perl world would
rejoice.
2.37) How can I set up a footer format to be used with write()?
While the $^ variable contains the name of the current header format,
there is no corresponding mechanism to automatically do the same thing
for a footer. Not knowing how big a format is going to be until you
evaluate it is one of the major problems.
If you have a fixed-size footer, you can get footers by checking for
line left on page ($-) before each write, and printing the footer
yourself if necessary.
Another strategy is to open a pipe to yourself, using open(KID, "|-")
and always write()ing to the KID, who then postprocesses its STDIN to
rearrange headers and footers however you like. Not very convenient,
but doable.
2.38) Why does my Perl program keep growing in size?
While there may be a real memory leak in the Perl source code or even
whichever malloc() you're using, common causes are incomplete eval()s
or local()s in loops.
An eval() which terminates in error due to a failed parsing
will leave a bit of memory unusable.
A local() inside a loop:
for (1..100) {
local(@array);
}
will build up 100 versions of @array before the loop is done.
The work-around is:
local(@array);
for (1..100) {
undef @array;
}
Larry reports that this behavior is fixed for perl5.
2.39) Can I do RPC in Perl?
Yes, you can, since Perl has access to sockets. An example of the rup
program written in Perl can be found in the script ruptime.pl at
the scripts archive on coombs.anu.edu.au . I warn you, however,
that it's not a pretty site, as it's used nothing from h2ph or c2ph,
so everything is utterly hard-wired.
2.40) What's the difference between delete and undef with %tables?
Pictures help... here's the %ary table:
keys values
+------+------+
| a | 3 |
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
And these conditions hold
$ary{'a'} is true
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is true
grep ($_ eq 'a', keys %ary) is true
If you now say
undef $ary{'a'}
your table now reads:
keys values
+------+------+
| a | undef|
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is FALSE
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is FALSE
grep ($_ eq 'a', keys %ary) is true
Notise the last two: you have an undef value, but a defined key!
Now, consider this:
delete $ary{'a'}
your table now reads:
keys values
+------+------+
| x | 7 |
| d | 0 |
| e | 2 |
+------+------+
and these conditions now hold; changes in caps:
$ary{'a'} is false
$ary{'d'} is false
defined $ary{'d'} is true
defined $ary{'a'} is false
grep ($_ eq 'a', keys %ary) is FALSE
See, the whole entry is gone!
2.41) How do I do a "tail -f" in Perl?
Larry says that the solution is to put a call to seek in yourself.
First try
seek(GWFILE, 0, 1);
If that doesn't work (depends on your stdio implementation), then
you need something more like this:
for(;;) {
for ($curpos = tell(GWFILE); $_ = <GWFILE>; $curpos = tell(GWFILE)) {
search for some stuff and put it into files
}
sleep for a while
seek(GWFILE, $curpos, 0);
}
--
Tom Christiansen tchrist@cs.colorado.edu
Consultant
Boulder Colorado 303-444-3212