[10960] in Perl-Users-Digest
Perl-Users Digest, Issue: 4561 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Jan 6 03:07:27 1999
Date: Wed, 6 Jan 99 00:01:38 -0800
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Wed, 6 Jan 1999 Volume: 8 Number: 4561
Today's topics:
Re: I don't know ANYTHING <nospam_gwynne@utkux.utk.edu>
Re: I wanna learn Perl real good..but first <nospam_gwynne@utkux.utk.edu>
If Larry Wall's listening out there.... <andrew@geac.co.nz>
Re: If Larry Wall's listening out there.... (Martien Verbruggen)
Re: If Larry Wall's listening out there.... (David Formosa (aka ? the Platypus))
Interlinked file link checker (was: Passing vars to HTM <crism@oreilly.com>
Re: looking for perl programmer <ajohnson@gatewest.net>
Re: newline <fpichard@siris.fr>
Re: Order of building a multi-level hash <uri@home.sysarch.com>
Re: Order of building a multi-level hash <dgris@moiraine.dimensional.com>
Re: PERL and permissions <eugene@verticalnet.com>
socket programming: picking a port automatically <dreeves@flip.eecs.umich.edu>
Special: Digest Administrivia (Last modified: 12 Dec 98 (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 5 Jan 1999 23:56:00 -0500
From: "Robert Gwynne" <nospam_gwynne@utkux.utk.edu>
Subject: Re: I don't know ANYTHING
Message-Id: <76uqdc$lbb$1@gaia.ns.utk.edu>
Being a newbie myself, I suggest that you learn some basic programming in C
or Pascal before tackling Perl. Perl's value is first that it is an
extremely elegant,compact, and powerful language. Second, it also has its
esoteric side, which may intimidate a beginner. Third, its highly useful for
writing CGI programs and for anything Unix; so if you are using Linux, Unix,
or doing Web programming, it's THE language.
If you want to start learning it, I suggest that you begin with Jon Orwant's
"Perl 5 Interactive Course". There is another CD based course on the
market, but I haven't seen it.
BTW: It's not cool to post messages to this group HTML formatted. It
makes people who write their own mail programs or are using Unix mail very
upset-- and these are the guys you don't want to upset.
Bob Gwynne
University of Tennessee
gwynne@utkux.utk.edu
FREED <wil@calweb.com> wrote in message news:3692df43.0@news1.jps.net...
I'm a complete numbskull when it comes to programming. Would someone please
take pity on me and help me to understand the wonders of the Perl language?
I'm interested in learning Perl, possibly C? I'm not sure though being that
I don't know anything about them. What is it that makes Perl so great?
What ways do you use it? I'm curious! Please help! Send e-mail to
professorbooty1@hotmail.com Thanks so much.
------------------------------
Date: Wed, 6 Jan 1999 00:01:19 -0500
From: "Robert Gwynne" <nospam_gwynne@utkux.utk.edu>
Subject: Re: I wanna learn Perl real good..but first
Message-Id: <76uqnb$lf5$1@gaia.ns.utk.edu>
See Lincoln Steins' Official Guide to Programming with CGI.pm.
Bob Gwynne
University of Tennessee
gwynne@utkux.utk.edu
Iain Lowe <ilowe@interlog.com> wrote in message
news:36923492.FBC1CF0F@interlog.com...
>Hello Perl folks.
>
>I've been dabbling in your dominion for awhile now, wanting to learn how
>to do things -- mostly CGI / Web form processing. I've looked at lots of
>tools and books, but I haven't found anything that really strikes my
>fancy.
>
>Currently, I use PerlBuilder on Win95 to develop pretty basic Perl form
>processors, and then tweak them where I can. Most of the books I've
>looked at only cover very simple forms, and spend most of their time
>explaining how to break up the query string into key/value pairs--the
>brain-dead stuff.
>
>SO, does anybody know of good resources where I can learn to do things
>like split a feedback form across a couple of pages without going all
>the way through the Camel book (that'll come).
>
>Thanks
------------------------------
Date: Wed, 6 Jan 1999 18:09:24 +1300
From: "Andrew Mayo" <andrew@geac.co.nz>
Subject: If Larry Wall's listening out there....
Message-Id: <76urmk$ncd$1@news.akl.netlink.net.nz>
Dear Larry and friends,
What a wonderful thing you have wrought.... but there's one small
detail.....
Those of us working in a Windows environment generally will use notepad as a
text editor. Simple-mindedly, notepad does *not* display line numbers. (it
also doesn't do brace matching, but this I can live with)
Unfortunately, perl's syntax checker appears to assume we'll be using
something like vi, and so I get things like
Missing right bracket at line 101...
and with no printed context of where the parser blew up, I have to count
lines. This gets rapidly tedious. Particularly since I am not a very
experienced Perl programmer, to say the least...
I cannot find a command-line switch to give me more detailed error
reporting; if there is one, my apologies, but what I really would like is
foo(x,y,z
^
Missing right bracket at line 101
(the ^ is supposed to be just after the z, should your browser mangle the
above)
Is there any way I can get Perl to print the context of the error message or
am I stuck counting lines. If the latter, may I humbly suggest this as an
enhancement for a future version?. While you're in there, how about a
severity level option for warnings, too, so that the -w flag could take a
parameter to indicate just how picky Perl ought to be.
PS:
At the risk of incurring the flames and wrath of a zillion Perl programmers,
and, worse, being a novice by my own admission, some aspects of Perl strike
me as worthy of mention, in comparison to other programming languages I have
used.
Pros
1. Incredibly powerful for text munging - which is why I am using it, since
I have a bunch of VB programs to mangle and I certainly wouldn't want to try
mangling them given VB's very limited string functions.
2. Portable and concise, yet efficient; can process a lot of stuff with
amazing speed on even humble hardware.
3. Rock-solid and extremely well documented (thanks, O'Reilly and
associates).
4. Can't beat the price.
5. Tied variables - what an excellent idea. Also the package concept and the
way objects have been implemented.
Cons
(note: I raise these because I want to write elegant yet maintainable code
and these cons seem to put barriers up in front of me - perhaps illusory
ones, of course, were I more knowledgeable)
1. Programs rapidly become unreadable if special care isn't taken to comment
carefully. This is due not just to leaning toothpick syndrome, which is
curable by careful choice of quote characters, as well as the quotemeta
function, but because almost every metacharacter sequence that could exist
has a semantic meaning which of course can't be deduced without looking it
up, until you become a Perl veteran. Of course C++ suffers badly from this,
too. At the other extreme, I know COBOL has been roundly condemned for its
verbosity but MOVE A TO B or PERFORM X VARYING Y FROM 1 BY 1 UNTIL Y > 3
express the intent in such a way that the syntax, once learnt, is never
forgotten. I have not written a line of COBOL for 10 years, but I think most
of the language is still with me - it has so much noise in it.
2. No macro pre-processor (AFAIK) which would let me add a bit of syntactic
sugar; most experienced C programmers find #define and #typedef are
invaluable for rendering sense out of chaos.
3. The variable argument list array is a nice idea but lack of proper
subroutine prototypes makes code rather obscure. Yes, I do see the section
on Perl 5.003 prototypes but, using VB as an example this time..
sub DrawImage(pic as Picture, optional rotation as degrees=zero_degrees)
it is relatively clear that the first argument is a picture, and the second,
optional argument is the rotation in degrees, with the default being zero
(degrees would be defined as an enum, probably, with perhaps four values for
0,90,180, and 270 degrees). Also the noiseword 'sub' tells me this routine
returns nothing, as does
'void' in C - how do I indicate this in Perl?.
I don't see how to write Perl code which comes close to being
self-documenting in this way, particularly function arguments.
A further, related issue is that arguments appear to be passed by reference,
so that special care needs to be taken to avoid side-effects and there does
not appear to be an easy way for the function prototype to define that an
argument or arguments should be passed by value instead, as there is in both
C and VB.
4. Lack of structures (aka VB types) and enums - at least, I can't find such
things. Sure, hashes are very nice, but they're not really the same thing.
5. Try as I might, I find the bind operator counter-intuitive. Operating on
$_ by default was probably a good idea back when Perl was sort of
ancestrally-related to Awk, but having to use $myvar=~.... to get around
this still seems peculiar; I may or may not actually be assigning to $myvar
depending on whether the right-hand side of the expression is a match or a
substitute.
6. Lack of strong typing. There are times when you want to prevent someone
from assigning a string to an integer and I don't see how to do this with
Perl - in fact, I don't know how to define a variable as being of a specific
type (other than an array, or a hash or a simple variable). Variables just
'spring into existence' as they did in early versions of BASIC - which can
lead to some very obscure programming errors. Does 'use strict' really help
here?.
7. Lack of structured exception handling (I may, however, be wrong here, I
just haven't found it yet).
8. No switch() or case statement, leading to nasty indented if... else if
type of constructs.
I conclude from these observations, some or all of which may turn out to be
mistaken, that Perl is suitable for fairly small programs (and indeed, was
designed this way, in all fairness) but that large Perl programming projects
will need considerable care in order to be maintainable. Has anyone out
there had experience in maintaining large (>10,000 line) Perl programs or
program suites, and if so, what techniques would you recommend to maximise
maintainability, other than the obvious recourse of commenting every line,
which is currently what I am doing?.
You may think that the notion of writing larger systems in Perl is
ludicrous, but consider that if you want platform portability your current
mainstream choices are
(a) C/C++ - compiled, hence slow development cycle, needs to be rebuilt on
each target platform, limited string processing (to say the least), easy to
create memory leaks.
(b) Java - primitive runtime libraries, lacks powerful string functions,
still evolving, not under ANSI or open source control and hence subject to
vendor change. Has to be compiled to JVM each time source is changed, unless
someone knows of an incremental Java compiler (in which case this would have
to be widely available across platforms
or
(c) Perl - open source, hence widely available for almost all platforms,
interpreted, short development cycle, powerful string processing,
extendable.
As we move to GUI RAD environments under, say, Linux, we need a quick
development language, similar to what we have with Visual Basic under
Windows. Is Perl going to be that future, or Java, or some other language?.
I understand someone's working on a Visual Perl, for instance.
------------------------------
Date: Wed, 06 Jan 1999 06:05:27 GMT
From: mgjv@comdyn.com.au (Martien Verbruggen)
Subject: Re: If Larry Wall's listening out there....
Message-Id: <H2Dk2.188$YE1.6520@nsw.nnrp.telstra.net>
In article <76urmk$ncd$1@news.akl.netlink.net.nz>,
"Andrew Mayo" <andrew@geac.co.nz> writes:
> Those of us working in a Windows environment generally will use
> notepad as a text editor. Simple-mindedly, notepad does *not*
> display line numbers. (it also doesn't do brace matching, but this I
> can live with)
>
> Unfortunately, perl's syntax checker appears to assume we'll be
> using something like vi, and so I get things like
Well, Notepad is just not an editor that was designed for programming
code. I personally don't find it much of a problem to only have the
line number to go on, and I am not entirely certain that it is that
easy to give you more. Of course, perl could try to guess where you
went wrong, but in many cases that is not where the problem lies.
My advice is to just get an editor that is good at editing code. there
are many freeware ones out there.
I could sort of draw an analogy here... You drive a car that has no
shock absorbers. Instead of getting a car that has them, or installing
shock absorbers on your current one, you expect the authorities to
provide a perfectly smooth surface on every road you plan to travel.
Hardly realistic isn't it?
> and with no printed context of where the parser blew up, I have to
> count lines. This gets rapidly tedious. Particularly since I am not
> a very experienced Perl programmer, to say the least...
Even more reason to get a decent editor. As said before, there are
many free ones. Alternatively, you could get the perl IDE that
ActiveState provides, I believe. I'm not too well informed about the
win32 perl stuff, but I have seen posts here talking about a beast
like that.
> foo(x,y,z
> ^
> Missing right bracket at line 101
But what if the code is actually:
sub {
# blabla
# hundreds of lines of code here
__END__
The compiler would have to either print all of the lines, or just the
last one, or something else nifty. And this is a simple case. Often
unterminated strings or regular expressions can cause very odd errors,
that appear to be located at a totally wrong place. It would be hard
to display a sensible chunk of code for that.
> (the ^ is supposed to be just after the z, should your browser
> mangle the above)
Use spaces and fixed width fonts, so that everyone can read it
correctly.
> Is there any way I can get Perl to print the context of the error
> message or am I stuck counting lines. If the latter, may I humbly
> suggest this as an enhancement for a future version?. While you're
> in there, how about a severity level option for warnings, too, so
> that the -w flag could take a parameter to indicate just how picky
> Perl ought to be.
if it is possible and if one of the people maintaining the perl
compiler feels like doing something about it, I'd applaud it. That is,
as long as it is optional.
> 3. Rock-solid and extremely well documented (thanks, O'Reilly and
> associates).
O'Reilly and associates just print the books. The actual writers are
much more important, and have also provided most of the online
documentation :)
> 1. Programs rapidly become unreadable if special care isn't taken to
> comment
I guess this is a matter of taste. None of my code (at least the stuff
I write nowadays) would look much better in other languages. You can
make Perl code very concise, but you don't have to.
Do you know about the /x modifier on the regular expression operators
(match and substitute)?
> 2. No macro pre-processor (AFAIK) which would let me add a bit of
> syntactic sugar; most experienced C programmers find #define and
> #typedef are invaluable for rendering sense out of chaos.
You can use the -P option on perl, although it is a bit unperlish to
do so. it will cause the script to be passed through the C
preprocessor first.
> A further, related issue is that arguments appear to be passed by
> reference, so that special care needs to be taken to avoid
> side-effects and there does not appear to be an easy way for the
> function prototype to define that an argument or arguments should be
> passed by value instead, as there is in both C and VB.
Well, that is arguable. Just make sure to use lexically scoped
variables. Don't meddle with @_ directly.
BTW, In C you only pass simple variables by value. For more complex
types, you normally pass a pointer (which itself is passed by value),
so you have to take care there as well. This is specifically true for
strings/character arrays.
> 4. Lack of structures (aka VB types) and enums - at least, I can't
> find such things. Sure, hashes are very nice, but they're not really
> the same thing.
There are modules to help you, perl supports an OO model which you can
use, you can use references etc.
> 5. Try as I might, I find the bind operator counter-intuitive.
> Operating on $_ by default was probably a good idea back when Perl
> was sort of ancestrally-related to Awk, but having to use
> $myvar=~.... to get around this still seems peculiar; I may or may
> not actually be assigning to $myvar depending on whether the
> right-hand side of the expression is a match or a substitute.
Hmm. So what would be the alternative? To not use $_ as the default?
You still need to bind a regexp operator to the variable you want to
match against. Assignment is not correct here, since
$a = /^foo.*/;
Does not say to me 'match in $a'. It says 'assign something to $a'.
Assignment and binding are two different sorts of operations. They
need different operators. And if you use the assignment as a binding
as well, how are you going to return the return values of those
fucntionalities?
> 6. Lack of strong typing. There are times when you want to prevent
> someone
Another arguable one. It is also a strength.
> from assigning a string to an integer and I don't see how to do this
> with Perl - in fact, I don't know how to define a variable as being
> of a specific type (other than an array, or a hash or a simple
You can't.
> variable). Variables just 'spring into existence' as they did in
> early versions of BASIC - which can lead to some very obscure
> programming errors. Does 'use strict' really help here?.
Yes, it does. The strict pragma forbids the use of variables that have
not been declared somehow. Nothing will 'spring' into existence. There
is however no typing, and there never will be in Perl. You could write
classes to do that, if you really need it.
> 7. Lack of structured exception handling (I may, however, be wrong
> here, I just haven't found it yet).
It's there, warn() die(), the carp module, signal handlers, etc..
> 8. No switch() or case statement, leading to nasty indented if...
> else if type of constructs.
Not necessarily. See the section 'Basic BLOCKs and Switch Statements'
in the perlsyn documentation (perldoc perlsyn)
> I conclude from these observations, some or all of which may turn
> out to be mistaken, that Perl is suitable for fairly small programs
Not so. Perl projects can become quite enormous, and I actually have a
few things here which are.
> (and indeed, was designed this way, in all fairness) but that large
> Perl programming projects will need considerable care in order to be
> maintainable. Has anyone out there had experience in maintaining
No more than large projects in other languages. Proper encapsulation,
modularisation and delegation will take care of that. proper software
design will take care of that. It is much, much less a function of the
language in use than it is of proper design and implementation.
> large (>10,000 line) Perl programs or program suites, and if so,
I never write code that has that many lines in one file. I immediately
split it up. And that is not a perl specific remark.
> what techniques would you recommend to maximise maintainability,
> other than the obvious recourse of commenting every line, which is
> currently what I am doing?.
Modularise. Extract. Encapsulate. Write documentation.
None of the above can be disposed of in any other programming
language.
> You may think that the notion of writing larger systems in Perl is
> ludicrous, but consider that if you want platform portability your
> current mainstream choices are
Not ludicrous at all. As I said: I do it a lot. You may want to have a
look at some of the modules or some of the bundles on CPAN. Some are
enormous.
> (a) C/C++ - compiled, hence slow development cycle, needs to be
> rebuilt on each target platform, limited string processing (to say
> the least), easy to create memory leaks.
C or C++ portable??? Not at all. Not in the least. I have nothing
against either, and use both, when appropriate, but I would never even
think about calling them portable.
> (b) Java - primitive runtime libraries, lacks powerful string
> functions, still evolving, not under ANSI or open source control and
> vendor change.
I think you're being excessively paranoid here :)
> (c) Perl - open source, hence widely available for almost all
> platforms, interpreted, short development cycle, powerful string
> processing, extendable.
Still Unix centered, which is fine by me, but seems to be a problem
for many other people. It doesn't have the nice GUI stuff, unless you
use Tk, which is fine by me, but seems to be a problem for many
other people. Perl is not interpreted, it is just compiled when it
gets loaded. This could be viewed as a weakness, and often is.
BTW, the other two languages are also quite extendable, unless you
mean something else than I do.
Each language has its strength. Each has it weaknesses. Instead of
trying to figure out which language is best in general, try to do it
for each project. Many of the languages above (in fact all three) can
cooperate, so code written in one is not necessarily wasted for an
application written in another.
Martien
--
Martien Verbruggen |
Webmaster www.tradingpost.com.au | Hi, Dave here, what's the root
Commercial Dynamics Pty. Ltd. | password?
NSW, Australia |
------------------------------
Date: 6 Jan 1999 06:31:24 GMT
From: dformosa@zeta.org.au (David Formosa (aka ? the Platypus))
Subject: Re: If Larry Wall's listening out there....
Message-Id: <slrn7960pq.c5e.dformosa@godzilla.zeta.org.au>
In article <76urmk$ncd$1@news.akl.netlink.net.nz>, Andrew Mayo wrote:
[...]
>Those of us working in a Windows environment generally will use notepad as a
>text editor. Simple-mindedly, notepad does *not* display line numbers. (it
>also doesn't do brace matching, but this I can live with)
You might have to get a new editor then. Line numbers are realy realy
importent. One way to solve this could be to use the following one
liner to find wich line perl is talking about,
perl -ne 'print qq{$.: $_}' scriptname.pl
Which will number each line for you.
Or you could use
perl -e 'print +(<>)[shift]' linenumber scriptname.pl
To get the line where the error is. Note this is not the best way to
get the N'th line as it has the side effect of loading in every other
line as well.
[...]
>(note: I raise these because I want to write elegant yet maintainable code
>and these cons seem to put barriers up in front of me - perhaps illusory
>ones, of course, were I more knowledgeable)
>
>1. Programs rapidly become unreadable if special care isn't taken to comment
>carefully.
This is infact commen to almost every usable languge no language is
truely self documenting, no matter what there desingers may say.
[...]
>2. No macro pre-processor (AFAIK) which would let me add a bit of syntactic
>sugar; most experienced C programmers find #define and #typedef are
>invaluable for rendering sense out of chaos.
By use of the -P option you can run your script threw the C
preproccessor.
>3. The variable argument list array is a nice idea but lack of proper
>subroutine prototypes makes code rather obscure. Yes, I do see the section
>on Perl 5.003 prototypes but, using VB as an example this time.
>
>sub DrawImage(pic as Picture, optional rotation as degrees=zero_degrees)
>
>it is relatively clear that the first argument is a picture, and the second,
>optional argument is the rotation in degrees, with the default being zero
>(degrees would be defined as an enum, probably, with perhaps four values for
>0,90,180, and 270 degrees).
sub ($;$) {
my ($pic,$rotation)=@_;
# ...
}
There is an _expermental_ feature that allows typing of objects so you
can do this.
sub ($;$) {
my Picture $pic = shift;
my Degress $degree = shift;
# ...
}
> Also the noiseword 'sub' tells me this routine
>returns nothing, as does 'void' in C - how do I indicate this in
>Perl?.
You can't realy, all perl subs return values.
[...]
>A further, related issue is that arguments appear to be passed by
>reference,
This is correct, thats why normaly the first step is to copy it into a
lexical.
[...]
>4. Lack of structures (aka VB types) and enums - at least, I can't find such
>things. Sure, hashes are very nice, but they're not really the same
>thing.
Hashes will give you everything that a structure type will give you
(and more). You can most probly create your own enumated type object
if you wish (but I bet there is already an enum type module on CPAN).
>5. Try as I might, I find the bind operator counter-intuitive.
This one I can't answer. Personaly I would like something that was
equliverlent was like s/// but acted like a function, that is taking
an arguemten and returning the value of what was substuted.
[...]
>6. Lack of strong typing.
Most of the time this is a fature.
> There are times when you want to prevent someone
>from assigning a string to an integer
You use regexps to check that the contents is sain.
[...]
> Variables just
>'spring into existence' as they did in early versions of BASIC - which can
>lead to some very obscure programming errors. Does 'use strict' really help
>here?.
Yes, use strict will prevent variables from springing into existent.
>7. Lack of structured exception handling (I may, however, be wrong here, I
>just haven't found it yet).
You make use of die to throw exceptions and eval { } to catch
them. See the docs for these functions.
>8. No switch() or case statement, leading to nasty indented if... else if
>type of constructs.
See the perl FAQ that comes with your perl for a number of switch equivlents.
[...]
--
Please excuse my spelling as I suffer from agraphia. See
http://www.zeta.org.au/~dformosa/Spelling.html to find out more.
How to win arguments on usenet http://www.zeta.org.au/~dformosa/usenet.html
------------------------------
Date: 06 Jan 1999 02:06:53 -0500
From: Chris Maden <crism@oreilly.com>
Subject: Interlinked file link checker (was: Passing vars to HTML::Parser/globals with strict/link checking)
Message-Id: <ker9t85182.fsf@rosetta.ora.com>
Here's what I came up with. Subject to my assumptions, which are
applicable for my data but strictly general, this works pretty well.
Maybe someone else will find it useful.
I am interested in hearing comments on my programming style (as my
formal CS training is (nearly) zero), as well as if anyone finds this
useful. It's primarily for sanity-checking interlinked sets of
documents (like the O'Reilly CDs), not for checking if your bookmarks
have gone stale.
#!/usr/local/bin/perl -w
# $Id: linkchek.pl 1.3 1999/01/06 07:05:03 crism Exp $
# Checks links in an interlinked web of documents.
# Limitations and assumptions:
# o Doesn't check any link with a colon in its URL (my anchors are all
# valid SGML NMTOKENS, so I know there are no colons there).
# o Must be run from the same directory as the files being checked, as
# relative URLs are handled relative to the current directory. This
# is bad design. Bite me.
# o Some HTML 4.0 elements with %URI; attributes are ignored. These
# are weird ones like <script> and <head> that I don't use links
# on. It should be easy enough to add support for them, though.
# If the first argument is -v, it'll be verbose. Otherwise, it won't.
# Usage: linkchek [-v] files
# I'm a good boy. Boy, is this a pain.
use strict;
{
# Create an HTML::Parser of our own.
package linkchek::Parser;
require HTML::Parser;
@linkchek::Parser::ISA = ('HTML::Parser');
# Hashes I'm going to populate.
my (%links, %names);
sub new
{
my $class = shift;
# Modify the hash of $self to keep our info.
my $self = bless {'_buf' => '',
'_strict_comment' => 0,
# The file currently being parsed. Must be
# set manually by the caller; HTML::Parser
# doesn't seem to give us access to this
# information, which is weird.
'file' => '',
# A reference to the %links hash. I tried
# to initialize an empty hash here directly,
# but it didn't work. I don't know why.
'links' => \%links,
# Ditto for the %names hash.
'names' => \%names
}, $class;
$self;
}
# Here's where all the work happens.
sub start {
my ($self, $tag, $attr, $attrseq, $origtext) = @_;
my ($name, $link);
# It might have a name, it might have a link.
if ($tag eq "a") {
# Store the link.
if ($link = $attr->{"href"}) {
addlinktohash ($self->{"links"}, $link, $self->{"file"});
}
# Store the name.
if ($name = $attr->{"name"}) {
${${$self->{"names"}}{$self->{"file"}}}{$name} = 1;
}
}
# Might have a link,
elsif ($tag eq "area") {
# ... so store it.
if ($link = $attr->{"href"}) {
addlinktohash ($self->{"links"}, $link, $self->{"file"});
}
}
# Make a note of the file itself.
elsif ($tag eq "html") {
%{${$self->{"names"}}{$self->{"file"}}} = ();
}
# Better have a link. Maybe two.
elsif ($tag eq "img") {
if ($link = $attr->{"src"}) {
addlinktohash ($self->{"links"}, $link, $self->{"file"});
}
if ($link = $attr->{"usemap"}) {
addlinktohash ($self->{"links"}, $link, $self->{"file"});
}
}
# Most likely has a link.
elsif ($tag eq "link") {
if ($link = $attr->{"href"}) {
addlinktohash ($self->{"links"}, $link, $self->{"file"});
}
}
# Has a name.
elsif ($tag eq "map") {
if ($name = $attr->{"name"}) {
${${$self->{"names"}}{$self->{"file"}}}{$name} = 1;
}
}
}
# Add file-and-anchor links to the hash structure.
sub addlinktohash {
my ($hashref, $link, $curfile) = @_;
my ($file, $anchor);
# But only if it's a local link. I don't check things that go
# elsewhere, and I know my anchors don't have colons. A more
# complex regexp could allow anchors with colons and still
# exclude outside links.
if ($link =~ /:/) {
return 0;
}
# Parse out the file reference and the fragment identifier.
($file, $anchor) = split /#/, $link;
# If we've got a file *and* an anchor,
if ($file && $anchor) {
# ... store the referring (current) file under the anchor
# under the target file.
push @{${$hashref->{$file}}{$anchor}}, ($curfile);
}
# If we just have an anchor,
elsif ($anchor) {
# ... store the referring (current) file under the anchor
# under the current file.
push @{${$hashref->{$curfile}}{$anchor}}, ($curfile);
}
# If we just have a file,
else {
# ... store the referring (current) file under the top of
# the target file.
push @{${$hashref->{$file}}{"#top"}}, ($curfile);
}
return 0;
}
}
# Mine! You can't have them!
my ($verbose); # Are we talkative today?
my ($p); # A parser instance.
my ($linkedfile); # An iterator over link targets.
my (%links); # A hash of the links.
my (@references); # An array of references to a bad file.
my ($anchor); # An interator over the anchors linked to in a
# target file.
# You've got to give some arguments. DWIM is in the next version.
if (!@ARGV) {
die "Usage: $0 [-v] files\n";
}
# Are we verbose?
if ($ARGV[0] eq "-v") {
$verbose = 1;
# If so, we don't want to try and parse the file "-v".
shift @ARGV;
}
else {
$verbose = 0;
}
# Fire up that parser!
$p = linkchek::Parser->new;
# Parse each of the files on the command line.
while ($p->{"file"} = shift @ARGV) {
# If the file's readable and a normal file,
if (-r $p->{"file"} && -f $p->{"file"}) {
# ... parse it,
$p->parse_file($p->{"file"});
}
else {
# ... otherwise, give an error.
print "Can't open file " . $p->{"file"} . " for parsing.\n";
}
}
# Make a copy of the parser's link hash. That's because we're going
# to need to parse more files, which will add any links in those files
# to the parser's hash, and we don't want to try and chase them down,
# too. Probably, I should just have it not add the links on that
# second pass, but I'm lazy.
%links = %{$p->{"links"}};
# So, for each file that there's a link to,
foreach $linkedfile (sort keys %links) {
# ... did we already parse it?
if (${$p->{"names"}}{$linkedfile}) {
# If so, no sense in checking references to it alone, since we
# know those are valid.
if ($links{$linkedfile}{"#top"}) {
if ($verbose) {
print "Link to $linkedfile OK.\n";
}
delete $links{$linkedfile}{"#top"};
}
}
else {
# If not, is it a normal file?
if (-f $linkedfile) {
# Then simple links to it are OK
if ($links{$linkedfile}{"#top"}) {
if ($verbose) {
print "Link to $linkedfile OK.\n";
}
# ... and don't need to be checked.
delete $links{$linkedfile}{"#top"};
}
# If there are any fragment links to the file,
if (keys %{$links{$linkedfile}}) {
if ($verbose) {
print "Need to parse $linkedfile.\n";
}
# ... we need to parse it for anchors.
$p->{"file"} = $linkedfile;
$p->parse_file($linkedfile);
}
}
# If the file doesn't exist, there's a problem.
else {
print "File $linkedfile does not exist.\n";
# Build the list of places from which the file was
# referenced.
foreach $anchor (sort keys %{$links{$linkedfile}}) {
push @references, @{$links{$linkedfile}{$anchor}};
}
print " Used in " . join ('; ', @references) . ".\n";
# Reset the variable.
@references = ();
# No sense in checking its anchors.
delete $links{$linkedfile};
}
}
# Does this file have references to fragments?
if (keys %{$links{$linkedfile}}) {
# Well, check them!
foreach $anchor (sort keys %{$links{$linkedfile}}) {
# Is the anchor in the list of known ones?
if (${$p->{"names"}}{$linkedfile}{$anchor}) {
if ($verbose) {
print "Link to #$anchor in $linkedfile OK.\n";
}
}
else {
print "Anchor #$anchor does not exist in $linkedfile!\n";
print " Used in " . join ('; ', @{$links{$linkedfile}{$anchor}}) . ".\n";
}
}
}
}
-Chris
--
<!NOTATION SGML.Geek PUBLIC "-//Anonymous//NOTATION SGML Geek//EN">
<!ENTITY crism PUBLIC "-//O'Reilly//NONSGML Christopher R. Maden//EN"
"<URL>http://www.oreilly.com/people/staff/crism/ <TEL>+1.617.499.7487
<USMAIL>90 Sherman Street, Cambridge, MA 02140 USA" NDATA SGML.Geek>
------------------------------
Date: Wed, 06 Jan 1999 01:54:50 -0600
From: Andrew Johnson <ajohnson@gatewest.net>
Subject: Re: looking for perl programmer
Message-Id: <369316CA.62CBE1C2@gatewest.net>
Uri Guttman wrote:
!
>
> >>>>> "DG" == Daniel Grisinger <dgris@moiraine.dimensional.com> writes:
>
> DG> Ack! You're right. I was thinking 4.5Mb/s for some reason.
>
> DG> I will now write `I will think while I type' 2<<31 times as
> DG> punishment. :-)
>
> i hate to burst your hairshirt bubble, but 2<<31 in perl is 0!
>
> 1030 > perl -le '$i = 2<<31 ; print $i'
> 0
> 1031 > perl -le '$i = 2<<30 ; print $i'
> 2147483648
>
> perhaps you meant 1<<31 times?
I do believe that Daniel meant exactly what he said: ' 2<<31' times
of writing out 'I will thinK while I type' ... I only think he
neglected the fact that he wrote it the one time in the post and
perhaps should have said '( (2<<31) + 1 )' times.
regards
andrew
------------------------------
Date: Wed, 06 Jan 1999 07:50:49 +0000
From: Francois PICHARD <fpichard@siris.fr>
Subject: Re: newline
Message-Id: <369315D9.48C4818C@siris.fr>
This is a multi-part message in MIME format.
--------------8AAA49CDBFFBD244AB9B8746
Content-Type: multipart/alternative;
boundary="------------56767491ACC51A1ECF11AD60"
--------------56767491ACC51A1ECF11AD60
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Herger Peter wrote:
> Hi all
>
> I've wrote a script like the following.
>
> #!/usr/bin/perl -w
> ######################################################################
> # (c) Herger Peter 29.12.98 peter.herger@swisslife.ch
> #This script gets the configfiles ones per week from the first
> #device on each router and stores it on
> su8000/usr/net/routers/rtconfigs/
> #
> ######################################################################
>
> use Net::FTP;
> $date = `date '+%m%d'`;
> $storedir = `date '+log%m%d'`;
>
> `mkdir /usr/net/routers/rtconfigs/$storedir`;
>
> #**************************** wfhgtv1 ********************************
> $dir = "1:";
> $host = "wfhgtv1";
>
> $ftp = Net::FTP->new($host, Timeout => 60) ||
> die "Cannot connect: $host";
>
> $ftp->login("Manager", "mars97ib") || die "Login failed";
>
> $ftp->cwd($dir) || die "Directory $dir doesn't exist";
> $ftp->binary();
> $ftp->get("config" ,
> "/usr/net/routers/rtconfigs/$storedir/confhgtv1.$date");
>
> $ftp->quit();
> #********************************************************************
>
> But in the second last line, there is a problem. The variable $storedir
> always includes a \n at the end. How can I suppress this \n ?
>
> Thanks a lot
>
> Peter Herger
Use the command : "chomp $storedir" before using your variable.
--
Cordialement.
Francois PICHARD
------------------------------------------------------------------
Tel: +33-1-41-97-96-15 SIRIS
Fax: +33-1-41-97-96-89 54, Place de l'Ellispe
Mel: fpichard@siris.fr 92983 La Defense Cedex
--------------56767491ACC51A1ECF11AD60
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Herger Peter wrote:
<blockquote TYPE=CITE>Hi all
<p>I've wrote a script like the following.
<p>#!/usr/bin/perl -w
<br>######################################################################
<br># (c) Herger Peter 29.12.98 peter.herger@swisslife.ch
<br>#This script gets the configfiles ones per week from the first
<br>#device on each router and stores it on
<br>su8000/usr/net/routers/rtconfigs/
<br>#
<br>######################################################################
<p>use Net::FTP;
<br>$date = `date '+%m%d'`;
<br>$storedir = `date '+log%m%d'`;
<p>`mkdir /usr/net/routers/rtconfigs/$storedir`;
<p>#**************************** wfhgtv1 ********************************
<br>$dir = "1:";
<br>$host = "wfhgtv1";
<p>$ftp = Net::FTP->new($host, Timeout => 60) ||
<br> die "Cannot connect: $host";
<p>$ftp->login("Manager", "mars97ib") || die "Login failed";
<p>$ftp->cwd($dir) || die "Directory $dir doesn't exist";
<br>$ftp->binary();
<br>$ftp->get("config" ,
<br>"/usr/net/routers/rtconfigs/$storedir/confhgtv1.$date");
<p>$ftp->quit();
<br>#********************************************************************
<p>But in the second last line, there is a problem. The variable $storedir
<br>always includes a \n at the end. How can I suppress this \n ?
<p>Thanks a lot
<p>Peter Herger</blockquote>
Use the command : "<b>chomp </b>$storedir" before using
your variable.
<pre>--
Cordialement.
Francois PICHARD
------------------------------------------------------------------
Tel: +33-1-41-97-96-15 SIRIS
Fax: +33-1-41-97-96-89 54, Place de l'Ellispe
Mel: fpichard@siris.fr 92983 La Defense Cedex</pre>
</html>
--------------56767491ACC51A1ECF11AD60--
--------------8AAA49CDBFFBD244AB9B8746
Content-Type: text/x-vcard; charset=us-ascii;
name="fpichard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Francois PICHARD
Content-Disposition: attachment;
filename="fpichard.vcf"
begin:vcard
n:PICHARD;Francois
tel;fax:+33-1-41-97-96-89
tel;work:+33-1-41-97-96-15
x-mozilla-html:FALSE
org:SIRIS
adr:;;54, Place de l'Ellipse;PARIS LA DEFENSE Cedex;;92983;FRANCE
version:2.1
email;internet:fpichard@siris.fr
x-mozilla-cpt:;23296
fn:PICHARD, Francois
end:vcard
--------------8AAA49CDBFFBD244AB9B8746--
------------------------------
Date: 06 Jan 1999 01:01:39 -0500
From: Uri Guttman <uri@home.sysarch.com>
Subject: Re: Order of building a multi-level hash
Message-Id: <x7ogodlz24.fsf@home.sysarch.com>
>>>>> "RJK" == Ronald J Kimball <rjk@linguist.dartmouth.edu> writes:
RJK> Uri Guttman <uri@ibnets.com> wrote:
r> $tree1{'Jones'} = "NY";
r> $tree1{'Smith'} = "NJ";
>>
r> $tree1{'Smith'}{'Bob'} = "CT";
>>
>> now Smith doesn't equal 'NJ' but rather an anon hash like { 'Bob' => 'CT' }
>>
>> you just dont try to print it and it is as lost as the method A example
RJK> The rest of your explanation is fine, but this part is incorrect.
RJK> $tree1{'Smith'} *does* still equal 'NJ', and there is no anonymous hash
RJK> { 'Bob' => 'CT' }. Instead, there is a named hash %NJ, and
RJK> $tree1{'Smith'} is used as a symbolic reference to it.
well he didn't say if he was using strict which would have disallowed
that and given him compiler errors. it would have made it obvious what
really happened.
perl -Mstrict=refs -e '$t{a}="b";$t{a}{c}="d";print "[$b{c}]\n"'
Can't use string ("b") as a HASH ref while "strict refs" in use at -e line 1.
i didn't realize you could do a symbol deref without a surrounding
${}. since symbol derefs are so deprecated, i wouldn't know some of its
finer syntax. maybe it is because it is a simple deref like a single $
can do.
either way he doesn't get what he expects. he needs to learn more about
HoH.
uri
--
Uri Guttman ----------------- SYStems ARCHitecture and Software Engineering
Perl Hacker for Hire ---------------------- Perl, Internet, UNIX Consulting
uri@sysarch.com ------------------------------------ http://www.sysarch.com
The Best Search Engine on the Net ------------- http://www.northernlight.com
------------------------------
Date: 05 Jan 1999 23:46:12 -0700
From: Daniel Grisinger <dgris@moiraine.dimensional.com>
Subject: Re: Order of building a multi-level hash
Message-Id: <m3ogoc526j.fsf@moiraine.dimensional.com>
rjk@linguist.dartmouth.edu (Ronald J Kimball) writes:
> The rest of your explanation is fine, but this part is incorrect. The
> value 'NJ' is *not* clobbered. It is used as a symbolic reference to a
> hash named %NJ.
Oops! Like Uri, I'll claim strict on the mind. :-)
Thanks, Ronald.
dgris
--
Daniel Grisinger dgris@moiraine.dimensional.com
perl -Mre=eval -e'$_=shift;;@[=split//;;$,=qq;\n;;;print
m;(.{$-}(?{$-++}));,q;;while$-<=@[;;' 'Just Another Perl Hacker'
------------------------------
Date: Tue, 05 Jan 1999 20:42:46 -0500
From: Eugene Sotirescu <eugene@verticalnet.com>
Subject: Re: PERL and permissions
Message-Id: <3692BF96.82CE42E5@verticalnet.com>
Bart Lateur wrote:
> Alejandro Eluchans wrote:
>
> >Does any body know how to change the permission of a PERL script from
> >nobody to a user with full privileges in a particular directory in order
> >to edit and create files using PERL without having to give full
> >permission to nobody.
>
> The magic word is: SUID or Set-UID ("set user ID"). Maybe look it up. It
> can let user "nobody" run this one particular script as if he was you.
> Er... "the owner of the script".
>
> It involves setting one bit in the file's access properties. You need to
> do this using Telnet, 'cos (AFAIK) no FTP client lets you do this.
>
> It's a bit hairy, though. In short: expect trouble.
>
> HTH,
> Bart.
Not all UNICES support suid.
------------------------------
Date: Wed, 6 Jan 1999 02:43:34 -0500
From: Daniel Reeves <dreeves@flip.eecs.umich.edu>
Subject: socket programming: picking a port automatically
Message-Id: <Pine.GSU.4.05.9901060235480.25197-100000@flip.eecs.umich.edu>
Is there a way for a server program written in perl to automatically pick
a free port and print it? (ie, "this server is listening on port x...")
Thanks,
Daniel
------------------------------
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 4561
**************************************