Initialising a hash

D

Dave Saville

I have a script that processes apache log files.

One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.

Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

1 is out. I was doing it but forgot all about it and one day deleted
the file on a "what;s that doing here?" thought.

I have changed to 2, but just wonder about the pros and cons of 2 vs 3
- if there are any.

TIA
 
R

Rainer Weikusat

Dave Saville said:
I have a script that processes apache log files.

One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.

Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

Considering that RFC2616 defines 41 response codes, I think I'd just
grap them from the table of contents, use a perl one-liner to munge that
into 'hash syntax',

perl -ane '$F[0] =~ /(\d+\.){2}\d+/ or next; $e = $F[2]; $_ =~ /\./ and last or $e .= " $_" for @F[3 .. $#F]; print($F[1], "=> '\''$e'\'',\n");'

(works for a shell with 'bourne-style quoting rules')

and include that literally in the code (as 'body' of a hash
initialization, obviously).
 
J

John Bokma

Dave Saville said:
I have a script that processes apache log files.

One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.

Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

4)

use HTTP::Status;

print status_message( $code ), "\n";
 
H

Huge

I have a script that processes apache log files.

One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.

Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

1 is out. I was doing it but forgot all about it and one day deleted
the file on a "what;s that doing here?" thought.

Which is why I always code the ability to have comments into such files
and comment them "HTTP Error codes, used by /usr/local/bin/apache_log_report",
or whatever.
 
J

Jim Gibson

Huge said:
Which is why I always code the ability to have comments into such files
and comment them "HTTP Error codes, used by /usr/local/bin/apache_log_report",
or whatever.

Which is why I always create either a backup system or a configuration
control system, but usually both.
 
X

Xho Jingleheimerschmidt

I have a script that processes apache log files.

One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.

Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

1 is out. I was doing it but forgot all about it and one day deleted
the file on a "what;s that doing here?" thought.

I have changed to 2, but just wonder about the pros and cons of 2 vs 3
- if there are any.

The main trade off for 2 is that you might someday decide you need your
__DATA__ section for something less amenable to a 3-ish solution than
this is.

Also, I suppose you might one day see the __DATA__ section and say
"What's that doing here" and delete it. If you are prone to doing that
sort of thing.

Xho
 
C

C.DeRykus

I have a script that processes apache log files.
One of the items it needs is a "number to english" look up of HTTP
error codes. There are around 80 of the things.
Given "200 OK" etc. per line I can see three ways of doing it:

1) External file, read and parse into a hash with the number as the
key.
2) Ditto but have the codes internally under __DATA__
3) Actually init as a hash - "code" => "english".

1 is out. I was doing it but forgot all about it and one day deleted
I have changed to 2, but just wonder about the pros and cons of 2 vs 3

I'd combine them:

my %CODE;
{ local($/,$_); $_=<DATA>; %CODE = /(...)...(...)/mg }
 
D

Dave Saville

Unfortunately I did not look in the file - I just went by the name.
:-(
Which is why I always create either a backup system or a configuration
control system, but usually both.

I do have a backup - but the deletion was over a year ago and I don't
keep them that long.
 
D

Dave Saville

4)

use HTTP::Status;

print status_message( $code ), "\n";

Thanks for that - Did not know of it - and I had it :) Specific
solution but I was also after the general case. Which others have
commented on.
 
D

Dave Saville

On Thu, 6 Feb 2014 04:08:35 UTC, Xho Jingleheimerschmidt

Also, I suppose you might one day see the __DATA__ section and say
"What's that doing here" and delete it. If you are prone to doing that
sort of thing.

LOL. Much, much less likely to delete a chunk of a script without too
much thought than a data file that appeared in a cgi directory.
Actually the decision was slightly more complicated than "Why's that
here? rm" but the details are irrelevant to the discussion in hand.
 
H

Huge

Which is why I always create either a backup system or a configuration
control system, but usually both.

Good ideas both, but they don't answer the question, "What's this file
for?"
 
D

Dave Saville

There have been a number of suggestions--including the right one,
HTTP::Status--but in the more general case I would say 1. there doesn't
seem to be any good reason not to write this as plain Perl code but 2.
this code should go in a module so it can be reused. That is, if
HTTP::Status didn't exist, you should have created it.

For the even-more-general case where the data to be represented is
complicated enough that it actually makes sense to store it in some
other format than Perl code and parse it every time, the fact that every
module gets its own __DATA__ section gives you a convenient place to put
things. For non-textual data or situations where multiple files are
required, you can use File::ShareDir.

Thanks Ben.

Maybe I should not have mentioned what the data was as it was the
general case I was after. OTOH, if I had not mentioned what the data
was I would not have found out about HTTP::Status. :)
 
D

Dave Saville

use HTTP::Status;

print status_message( $code ), "\n";

I have read and think I understood the code of this module. What I
don't understand is how does one make use of the mnemonics? I can't
find an example.

I thought what it did was setup subroutine(s) that take no paramteters
and return the code number. But anything I tried seems to want one to
code RC_LOCKED() rather than RC_LOCKED which I thought was the general
idea.
 
R

Rainer Weikusat

Ben Morrow said:
There have been a number of suggestions--including the right one,
HTTP::Status--

The 'right' solution (in the sense of 'sensibly engineered') would be to
have a textual database file similar to the already existing ones, eg,
protocols or services, which can be maintained independently of anything
executable which happens to use it and which is generally useful and not
tied to a particular 'executable code module' written in a particular
language.

If the mapping is hard-coded, anyway, the next most convenient
thing would to transfer the corresponding hasg from Status.pm to the script
using it and thus, at least avoid the useless function call and make
this list maintainble without having to futz around with some third
party code module prone to being replaced inadvertently without
realising the damage until a much less convenient later time.

"Someone else wrote it and I know how to get it for free!" may also be a
sensible approach, but only insofar this helps avoiding a 'critical'
competence deficit or to increase the billed_time / actual_work_time
quotient in order to make someones conslutancy more economically viable,
although it would be debatable if die-hard 'religious' short-termism is
such a good idea in the long run.
 
R

Rainer Weikusat

[...]
increase the billed_time / actual_work_time quotient in order to make
someones conslutancy more economically viable, although it would be
debatable if die-hard 'religious' short-termism is such a good idea in
the long run.

Personal addition: My arguably limited experience with these people is
one of 'Caveat emptor' with the 'Caveat' being such a huge part of this
that 'run away screaming' should be considered as more sound
alternative, ie, in the end, the code will have to be replaced, anyway,
if one doesn't want to keep losing deals, while the 'consultant' has long
since sought a greener pasture elsewhere. I apologize to everyone who
actually does this as an honest business instead of a 'promise castles
in the air, get $$$ in return, let someone else deal with the debris'
scam.
 
T

Tim McDaniel

Maybe I should not have mentioned what the data was as it was the
general case I was after.

I think you should. In my experienc: almost always, when someone asks
a general question and later gets to the specific details, it turns
out that the specific details change the answer.
 
P

Peter J. Holzer

I have read and think I understood the code of this module. What I
don't understand is how does one make use of the mnemonics? I can't
find an example.

I thought what it did was setup subroutine(s) that take no paramteters
and return the code number.

This works for me:

#!/usr/bin/perl
use warnings;
use strict;
use v5.10;

use HTTP::Status qw:)constants);

say HTTP_FOUND;
say "Location: http://example.com";
say "";
__END__

hp
 
R

Rainer Weikusat

I think you should. In my experienc: almost always, when someone asks
a general question and later gets to the specific details, it turns
out that the specific details change the answer.

There's a general answer to these kind of questions and it is "use a
textual database in a well-known format which can be maintained
indepdently of your present code and used independently of the
programming language your present code happens to be written in". In
case you'd rather have something simple, use a hard-coded hash _in
your script_. Suitable places for getting the data are ...

"Someone else already wrote a script with such a hard-coded list in it
and made it available for free download, so all you really have to do is
download it and tack the two scripts together somehow" is not among the
sensible answers, not even if the code attached to the other hard-coded
list happens to be useless for anything but accessing it in an
inefficient way.

Losely related question: Isn't there a newsgroup for all of this "OMG!
Free Download available!! Run to get there while stocks last!!!"
traffic? Or alternatively, is there a newsgroup for questions and
discussions about Perl and not about "OMG! ..."?
 
D

Dave Saville

This works for me:

#!/usr/bin/perl
use warnings;
use strict;
use v5.10;

use HTTP::Status qw:)constants);

say HTTP_FOUND;
say "Location: http://example.com";
say "";
__END__

Not on 5.8.2 :) Seems you need to qw( <the ones you need> ). There
is no generic that gets the lot. Thanks for the pointer though.
 
P

Peter J. Holzer

I thought what it did was setup subroutine(s) that take no paramteters
and return the code number.

This works for me: [...]
use HTTP::Status qw:)constants);

say HTTP_FOUND;
[...]

Not on 5.8.2 :)

Probably less a question of your Perl version as that of HTTP-Message.
On my workstation I have 6.03, on a server with Perl 5.8.0 I have 1.28,
which indeed doesn't export the :constants bundle. You could probably
upgrade HTTP-Message, though that might depend on some newer Perl
version.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Help with a hash 4
Read a hash 5
traversing a hash structure 3
data to hash 1
Push regex search result into hash with multiple values 14
hash of arrays 1
multiple text replacements from a hash 2
simple hash 3

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top