[22234] in Perl-Users-Digest
Perl-Users Digest, Issue: 4455 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Jan 23 14:06:16 2003
Date: Thu, 23 Jan 2003 11:05:10 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Thu, 23 Jan 2003 Volume: 10 Number: 4455
Today's topics:
Advice for relative newbie on perl compiler... <adamcheney@spamtrap.kiwis.co.uk>
Re: Attempting to run a simple Win Perl script without <charlest@indysoft.com>
Re: Can I store an array into a DataBase? <bart.lateur@pandora.be>
Re: Converting a string to a valid date.. (Tad McClellan)
Re: Converting a string to a valid date.. (Anno Siegel)
Dynamically Declaring Variables (Dave Fraleigh)
Re: function overriding (Tad McClellan)
Re: hash of arrays using variable array names <uri@stemsystems.com>
Re: hash of arrays using variable array names <nobull@mail.com>
Re: hash of arrays using variable array names <nobull@mail.com>
Re: hash of hashes of arrays <avishal@vsnl.net>
Re: hash of hashes of arrays <nobull@mail.com>
Re: hash of hashes of arrays (Tad McClellan)
Re: Help With Nested Hash/Array Requested <charlest@indysoft.com>
Re: Help With Nested Hash/Array Requested <charlest@indysoft.com>
Re: Help With Nested Hash/Array Requested (Anno Siegel)
Re: Help With Nested Hash/Array Requested <charlest@indysoft.com>
Is there a better way to check to see if a date lies w <mothra@nowhereatall.com>
Re: Is there a better way to check to see if a date li <fm_duendeBASURA@yahoo.com>
Re: Is there a better way to check to see if a date li <fm_duendeBASURA@yahoo.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 23 Jan 2003 16:05:54 +0000
From: Adam Cheney <adamcheney@spamtrap.kiwis.co.uk>
Subject: Advice for relative newbie on perl compiler...
Message-Id: <3e301466.0@entanet>
Hi All,
Just a quick bit of advice, please...
I am writing a number of ClearCase trigger scripts at the moment, and
I'm thinking about deploying them as executables. I see three major
advantages in this approach:
1) Perl version - the scripts (or exe) will actually get executed
locally on users' (Win32) machine, even though they're stored in a
central network location. Using executables ensures that I don't need
to worry about installing Perl or the particular version present.
2) Speed - I reckon this approach will be considerably faster.
3) Security - this is Windoze, after all. Scripts will be version
controlled, and then compiled before deployment to the network storage
location.
First, may I get your opinions on my reasons for deploying executables?
Second, your opinions on what to use (current favourites are PerlApp
from ActiveState or Perl2Exe from IndigoSTAR)? (Ideally, I'd like to
consider freeware products, too)
Thanks for your help - Adam Cheney...
------------------------------
Date: Thu, 23 Jan 2003 13:06:52 -0500
From: "Charles R. Thompson" <charlest@indysoft.com>
Subject: Re: Attempting to run a simple Win Perl script without the use of a window.
Message-Id: <v30bptf7ggar0e@corp.supernews.com>
As Jurgen previously noted, wperl is where you need to be looking. For a
working example, you might take a look at the PopFile project as it runs as
a background task in windows.
Good Luck,
CT
> Is it possible to run the script in a silent mode
> where by the user does not see a window pop up?
------------------------------
Date: Thu, 23 Jan 2003 16:10:40 GMT
From: Bart Lateur <bart.lateur@pandora.be>
Subject: Re: Can I store an array into a DataBase?
Message-Id: <bv303vkq3q16ic4a8svedgoajojfidgce2@4ax.com>
Francesco Moi wrote:
>I'm working with Perl and MySQL, and I would like to store an
>array (@my_array) into a DataBase, so that I can handle it.
>
>Is it possible?
The sane thing to, would be to have an extra table just for this array.
Provide (at least) two columns. In column one, insert the ID of the row
you want to attach the data to. In Column two, insert the value. Provide
as many rows with this one ID as you have array elements.
The nutty thing to do, would be to use a BLOB field, and use Storable to
compress the array into a scalar (string), and to expand it back to an
array. Actually, "compress" and "expend" are not the proper terms,
Storable names it "freeze" and "thaw", while in Java lingo, they speak
of "serialisation".
This approach is nutty, because there's no way to make any sense of the
database contents, except by using a Perl script. Actually, people
sometimes do this kind of things, see for example, MLDBM on CPAN. But
that is not in an ordinary SQL database, that's a Berkeley database, a
whole different beast.
If you still like the idea, but you have to share the data with PHP
scripts, it's better to use a format PHP can handle as well: see
serialize() and unserialize() in the PHP docs.
<http://www.php.net/manual/en/function.serialize.php>
Somebody wrote a Perl module that handles this rather simple format
(which is an advantage: it remains reasonable readable without external
tools, it's a bit similar to what Data::Dumper produces) and put a
pointer to it in the user comments at the above site:
<http://hurring.com/code/perl/serialize/>
I've tried it out. I've not done much with it just yet, but it appears
to be working.
--
Bart.
------------------------------
Date: Thu, 23 Jan 2003 12:13:16 -0600
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: Converting a string to a valid date..
Message-Id: <slrnb30c5s.aqs.tadmc@magna.augustmail.com>
Bullet <no_spam@fromyou.thanks-anyways.com> wrote:
>> my %shortmonths;
>> @shortmonths{ qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)} =
>> 1 .. 12;
> Why does the Hash get declared as an array?
There is no array anywhere in that code snippet.
> I
> learned a long time
> ago to stop dismissing things as typos..
Then you're more insightful than many hereabouts... :-)
> whats actually goin on?
The above is a "hash slice", as documented in the "Slices" section of:
perldoc perldata
There are also 2 other types of slices...
> Also.. in the earlier submission.. was this snippet..
> which I pretty much understand.. except for the last part..
> whats the @de[2,0] about?
...that is one of the other 2 types of slices, namely an "array slice".
A "list slice" is the 3rd type of slice.
> Why wouldnt that simply be $de[0]
Because then sprintf() wouldn't have the 4 "things to print"
that are specified in its format string, it would only have 3.
> sub d_convert {
> my @de = split /,?\s+/, $_[ 0 ];
> return sprintf '%04d-%02d-%02d %s', $de[3], $shortmonths{$de[1]},
> @de[2,0];
> }
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: 23 Jan 2003 18:33:40 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Converting a string to a valid date..
Message-Id: <b0pci4$69r$1@mamenchi.zrz.TU-Berlin.DE>
Bullet <no_spam@fromyou.thanks-anyways.com> wrote in comp.lang.perl.misc:
> > my %shortmonths;
> > @shortmonths{ qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)} =
> > 1 .. 12;
> >
> > Anno
>
> Often I see code such as the chunk above.. and cant figure it out without
> pulling out
> the PERL book and working through it.. is it just me or in a lot of cases
> wouldnt it just
> be easier for anyone who has to maintain the code to leave it a bit more
> simple?
You are right in observing that this is a bit harder to read than the
straight { Jan => 1, ...}. Its advantage is that it's easy to check.
Once you are sure you have listed all the months in order, the workings
of Perl make sure that the numbers 1 to 12 are assigned to them in
sequence. When you state each month/number pair separately you must
check them all. Getting it right is right up there with readability :)
> For instance in the above snip.. Because I know what the orginal code did..
> I know what
> its supposed to do.. other than that I would be lost if I were to see that
> in someone elses
> code. .
>
> Why does the Hash get declared as an array? and why in an Array context is
> the array defined
> using {} curlys instead of parentheses.. is that some kind of black magic? I
> learned a long time
> ago to stop dismissing things as typos.. whats actually goin on? Does this
No black magic, it's a very useful bit of Perl syntax called slices.
You can use parts of a hash as a list (therefore a leading "@", even with
a hash). You list the elements you want to access between normal hash
braces "{}". That's the strange expression "@shortmonths{ ...}" up there.
Slices are described in detail in perldata.
> example really mean
> that PERL really treats all arrays as hashes with numeric keys? Hmmm.. ?
Not at all. Arrays are arrays and not hashes in disguise.
> Also.. in the earlier submission.. was this snippet..
> which I pretty much understand.. except for the last part..
> whats the @de[2,0] about? Why wouldnt that simply be $de[0]
>
> sub d_convert {
> my @de = split /,?\s+/, $_[ 0 ];
> return sprintf '%04d-%02d-%02d %s', $de[3], $shortmonths{$de[1]},
> @de[2,0];
> }
It's another application of slices, an array slice in this case.
"@de[2,0]" is just a shorter way of writing "$de[ 2], $de[ 0]".
[more questions snipped]
Anno
------------------------------
Date: 23 Jan 2003 11:04:08 -0800
From: dave@fraleigh.net (Dave Fraleigh)
Subject: Dynamically Declaring Variables
Message-Id: <22f677f.0301231104.7cf4ee17@posting.google.com>
Hi,
I'm trying to write a statement that will take values read from a
config file and declare variables based on these values...
$theHashSymbol = "\%";
$theReferenceSymbol = "\$";
$theName = "subjects";
$theReference = "\\\{key\\\$subject\\\}";
$theFileName = "subjects.csv";
$theElements = "surname,given,initial"
$theCreateReferenceLine = $theReferenceSymbol . $theName . "TestRef =
"\"" . $theReference . "\";";
$theCreateFileNameLine = $theReferenceSymbol . $theName . "TestFile =
\"" . $theFileName . "\";";
$theCreateHashLine = $theHashSymbol . $theName . "TestHash =
&theFunction(" . $theReferenceSymbol . $theName . "TestFile" .
",\"keylookup\");";
eval($theCreateReferenceLine);
eval($theCreateFileNameLine);
eval($theCreateHashLine);
I'm trying to force my script to generate a variable called
"%subjectsTestHash" which contains the hash value tossed by a function
"theFunction()".
When I step through each statement, it seems to work. In fact, If I
eval() the last statement and assign it to another hash: %aHash =
eval($theCreateHashLine);, I can inspect the hash. Otherwise though,
I can't use the variable that I've "created" by evaluating the
dynamically-created statement.
So, in short, does anybody know how to dynamically create variables
based on values stored in other variables?
If so, how?
Thanks very much. Please reply via email.
Dave
------------------------------
Date: Thu, 23 Jan 2003 11:58:39 -0600
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: function overriding
Message-Id: <slrnb30baf.aqs.tadmc@magna.augustmail.com>
David <perl-dvd@darklaser.com> wrote:
> "Anno Siegel" <anno4000@lublin.zrz.tu-berlin.de> wrote in message
> news:b0oidl$9vo$3@mamenchi.zrz.TU-Berlin.DE...
>> David <perl-dvd@darklaser.com> wrote in comp.lang.perl.misc:
>>
>> > I've got a nice test of this groups skills.
>>
>> No, thanks. Trying to present a mundane question as a "challenge"
>> is not going to win you points.
>
> If you can't say something helpful, please refrain from posting.
And what is it about _your_ followup that is helpful then?
Or does that "rule" or yours only apply to "everybody else"?
> Jerk ... *plonk*.
sympathetic *plonk*
(hey! you are already in there, it seems you've changed your posting address)
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: Thu, 23 Jan 2003 17:38:00 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: hash of arrays using variable array names
Message-Id: <x7n0lrpy14.fsf@mail.sysarch.com>
>>>>> "q" == qanda <fumail@freeuk.com> writes:
q> Hi all, the following script appears to work (but only if I turn off
q> strict). I'm still learning, so can anyone tell me if anything is
q> particularly bad about this, could it be done more elegantly? The
q> objective is to pass a string into a function that can then be used to
q> load an array with certain records.
ok, i now have a chance to use my new polemic about the evils of
symrefs. enjoy!
RULE: symrefs are ONLY needed when you MUST mung the SYMBOL TABLE.
let's examine that rule. first, what is the symbol table? it is just a
hash tree with used by perl for symbols. it has no special powers in
itself.
therefore ANY regular hash tree (using hard references) will be able to
do the same job.
and what are the advantages of using a regular hash tree?
1. it is safer - no accidental screwing around with other data
2. it can be private - the hash tree is accessible only from its
root hash or reference. symbol table trees are ALWAYS named
and accessible. regular hashes can be anonymous.
3. it can be easily garbage collected. if the tree goes out of
scope it will be nicely collected (assuming other refs to it
are clearer or never existed). a tree in the symbol table
must be explicitly deleted as it will never go out of scope.
4. you can have multiple regular hash trees - many anon hashes
can be easily made and passed around. only a single tree of
any given name can be in the symbol table.
5. you can cleanly data::dumper regular hashes. you can then
store them in a file or DB and reload them for persistant
data or object. dumping the symbol table can be very ugly as
it will include all the other glob info you don't want.
there are other reasons too. if you have some good ones, post them and i
will add them here and in other places where i am working on this polemic.
so the upshot is that PLAIN DATA STRUCTURES should not be using the
symbol table. if you are, then your code is BAD, BROKEN, WILL SHOOT YOU
IN THE FOOT, MURDER YOU IN BED and it will GIVE YOU BAD BREATH.
now repeat after me:
symrefs are ONLY needed when you MUST mung the SYMBOL TABLE.
almost NO ONE NEEDS TO MUNG the SYMBOL TABLE. it is mostly for exporting
functions and variable and the Exporter module does that fine. there are
real needs to mung the symbol table but i have yet to see a newbie have
one.
so, i hope that help. turn on strict, rewrite the code to use real
references (others here will assist that for sure), and never use
symrefs again (UNLESS YOU ARE MUNGING THE SYMBOL TABLE).
SYMREFS ARE FOR SYMBOLS, NOT DATA
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class
------------------------------
Date: 23 Jan 2003 18:11:23 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: hash of arrays using variable array names
Message-Id: <u9y95b3fec.fsf@wcl-l.bham.ac.uk>
fumail@freeuk.com (qanda) writes:
> Hi all, the following script appears to work (but only if I turn off
> strict).
That's because it contains a bug that actually cause it to use a
sybolic reference where you are trying to use a real one. You get
away with it because symbolic reference work - up to a point.
You are trying to create an anoymous array but you actually create one
called @bb.
> I'm still learning, so can anyone tell me if anything is
> particularly bad about this,
It contains a mistake.
> could it be done more elegantly?
Correct the mistake.
> my %hoa= (
> $atype,
> $btype,
> );
You really meant to say:
my %hoa= (
$atype => undef,
$btype => undef,
);
Or:
my %hoa= (
$atype => [],
$btype => [],
);
But it is sufficient to just say:
my %hoa;
And that's not the only inelegant thing...
The hash %hoa is global (as in file-scoped) this is stylisitically
poor. You should consider passing it as an argument.
> $hoa{$atype}[ $#{ $hoa{$atype} }+1 ] = $_;
The statement:
$foo[ $#foo +1 ] = bar();
Is better witten as:
push @foo, bar();
> if( $flds[0] eq $atype ) {
> $hoa{$atype}[ $#{ $hoa{$atype} }+1 ] = $_;
> }
> elsif( $flds[0] eq $btype ) {
> $hoa{$btype}[ $#{ $hoa{$btype} }+1 ] = $_;
> }
The constuct:
if( $foo eq 'a' ) {
frobnicate('a');
} elsif ( $foo eq 'b' ) {
frobnicate('b');
}
Is better written as:
if( $foo eq 'a' || $foo eq 'b' ) {
frobnicate($foo);
}
Sometimes, if unecessary frobnication of other values is not overly
expensive, then it's simpler still:
frobnicate($foo);
> my @flds = split( /,/, $_, -1 );
Why the -1? You only ever use $flds[0] anyhow?
> print STDOUT "aa_array: $hoa{$atype}[0]\n";
STDOUT is the default output stream unless you've been playing with select.
#!/usr/bin/perl
use warnings;
use strict;
sub func1 {
my %hoa;
local $_;
while( <DATA> ) {
chomp;
my ($fld0) = split /,/;
push @{$hoa{$fld0}}, $_;
}
\%hoa;
}
sub func2 {
my $hoa = shift;
my $type = shift;
print "printing (arg)$type ...\n";
for my $i( 0 .. $#{ $hoa->{$type} } ) {
print " $hoa->{$type}[$i]\n";
}
}
my $hoa = func1();
func2($hoa,'aa');
func2($hoa,'bb');
__DATA__
aa,f2,f3,f4,line1
bb,f2,f3,f4,line2
cc,f2,f3,f4,line3
dd,f2,f3,f4,line4
aa,f2,f3,f4,line5
bb,f2,f3,f4,line6
------------------------------
Date: 23 Jan 2003 18:25:16 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: hash of arrays using variable array names
Message-Id: <u9ptqn3er7.fsf@wcl-l.bham.ac.uk>
Uri Guttman <uri@stemsystems.com> writes:
> >>>>> "q" == qanda <fumail@freeuk.com> writes:
>
> q> Hi all, the following script appears to work (but only if I turn off
> q> strict). I'm still learning, so can anyone tell me if anything is
> q> particularly bad about this, could it be done more elegantly? The
> q> objective is to pass a string into a function that can then be used to
> q> load an array with certain records.
>
> ok, i now have a chance to use my new polemic about the evils of
> symrefs. enjoy!
Actually if you look carefully you'll see the OP wasn't, despite what
he said in the suject line, trying to use symbolic references.
There was just a mistake in the HoA initalisation that meant that one
of the keys ended up as a value.
I'd got fairly far into expounding the evils of symbolic references
before I realised this.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Thu, 23 Jan 2003 22:52:06 +0530
From: Vishal Agarwal <avishal@vsnl.net>
Subject: Re: hash of hashes of arrays
Message-Id: <b0p7qs$nb4$1@news.vsnl.net.in>
Bart van den Burg wrote:
> hi
>
> I'm trying to create a hash of hashes of arrays, but I'm getting really
> confused here
> I'm creating it like this:
>
> my %channels = ("#channel1" => {"ops" => [], "voice" => [], "normal" =>
> []}, "#channel2" => {"ops" => [], "voice" => [], "normal" => []});
>
> at first, I want to add some "ops" to the list, so I do:
>
> unshift($channels}{"#channel1"}{"ops"}, "nickname");
>
> in return, I get the error:
> Type of arg 1 to unshift must be array (not hash element) at ./rb.pl line
> 114, near ""nickname")"
>
> Then I tried to create arrays first, then throw them in the hash:
>
> my (@ops);
> unshift(@ops, "nickname");
> $channels{$channel}{"ops"} = @ops;
> print $channels{$channel}{"ops"}[0]."\n";
>
> which gave me:
> Can't use string ("1") as an ARRAY ref while "strict refs" in use at
> ./rb.pl line 117.
>
>
> Could anyone tell me how to do this correctly?
>
> Thanks in advance
> Bart
hi,
try doing:
unshift @{$channels{"#channel1"}{ops}}, "nickname";
instead of:
unshift($channels}{"#channel1"}{"ops"}, "nickname");
also, for the other method, try:
$channels{$channel}{"ops"} = [@ops];
instead of:
$channels{$channel}{"ops"} = @ops;
hope it helps
- vishal
------------------------------
Date: 23 Jan 2003 17:37:39 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: hash of hashes of arrays
Message-Id: <u93cnj4vj0.fsf@wcl-l.bham.ac.uk>
"Bart van den Burg" <news@tvreclames.nl> writes:
> I'm trying to create a hash of hashes of arrays
"hash of hashes of arrays" is lazy shorthand terminolgy.
Lazy terminology is fine so long as everyone knows what we're _really_
talking about is a "hash of references to hashes of references to
arrays".
> but I'm getting really confused here
Quite. You are confusing yourself because, you are using shorthand
terminology then trying to interpret it literally.
> I'm creating it like this:
>
> my %channels = ("#channel1" => {"ops" => [], "voice" => [], "normal" => []},
> "#channel2" => {"ops" => [], "voice" => [], "normal" => []});
>
> at first, I want to add some "ops" to the list, so I do:
>
> unshift($channels{"#channel1"}{"ops"}, "nickname");
That's not got ballenced brackets, I assume you really meant:
unshift($channels{"#channel1"}{"ops"}, "nickname");
> in return, I get the error:
> Type of arg 1 to unshift must be array (not hash element) at ./rb.pl line
> 114, near ""nickname")"
That is correct. The argument you have given is a hash element that
contains a refernce to a hash.
To get an array from an expression that yeilds a reference to an array
you wrap it in @{}.
unshift(@{$channels{"#channel1"}{"ops"}}, "nickname");
> Then I tried to create arrays first, then throw them in the hash:
>
> my (@ops);
> unshift(@ops, "nickname");
> $channels{$channel}{"ops"} = @ops;
> print $channels{$channel}{"ops"}[0]."\n";
>
> which gave me:
> Can't use string ("1") as an ARRAY ref while "strict refs" in use at ./rb.pl
> line 117.
Same mistake again. You want a reference to @ops.
$channels{$channel}{ops} = \@ops;
> Could anyone tell me how to do this correctly?
perldoc perlreftut
perldoc perllol
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Thu, 23 Jan 2003 12:06:14 -0600
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: hash of hashes of arrays
Message-Id: <slrnb30bom.aqs.tadmc@magna.augustmail.com>
Bart van den Burg <news@tvreclames.nl> wrote:
> I'm trying to create a hash of hashes of arrays, but I'm getting really
> confused here
> I'm creating it like this:
>
> my %channels = ("#channel1" => {"ops" => [], "voice" => [], "normal" => []},
> "#channel2" => {"ops" => [], "voice" => [], "normal" => []});
So far so good, as verified by the Data::Dumper module:
print Dumper(\%channels), "\n";
> at first, I want to add some "ops" to the list, so I do:
>
> unshift($channels}{"#channel1"}{"ops"}, "nickname");
^
^
That is not your real code. Please don't waste our time troubleshooting
code that does not even exist.
Do not re-type Perl code
Use copy/paste or your editor's "import" function rather than
attempting to type in your code. If you make a typo you will get
followups about your typos instead of about the question you are
trying to get answered.
> in return, I get the error:
> Type of arg 1 to unshift must be array (not hash element) at ./rb.pl line
> 114, near ""nickname")"
I do to, after fixing the typo that you introduced.
> Could anyone tell me how to do this correctly?
Apply "Use Rule 1" from:
perldoc perlreftut
First, pretend it is a plain old everyday array:
unshift( @array, "nickname");
Then replace the _name_ of the array with a block:
unshift( @{ }, "nickname");
Then put something in the block that returns a reference to an array:
unshift( @{$channels{"#channel1"}{"ops"}}, "nickname");
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: Thu, 23 Jan 2003 12:46:51 -0500
From: "Charles R. Thompson" <charlest@indysoft.com>
Subject: Re: Help With Nested Hash/Array Requested
Message-Id: <v30akci67e7lea@corp.supernews.com>
Hi Uri,
Thanks for the lashing and helpful comments. Very long time no see. I'm
almost ashamed to be caught by you with such lazy code after you are the guy
who essentially taught me so much about hashes and whatnot. :) Here's my
newest effort after some study. There are a few things I wouldn't mind input
on from the group as this is going to the open source awstats script project
over on sourceforge and I don't really want to deliver it until I feel
pretty good about the core code. Essentially this plugin allows webmeisters
the ability to translate IPs and domains to company names from a flat file.
For general websites it's useless but for corporate it allows some idea of
what other corporate level clients are visiting our site.
From the last posted version I was able to:
- remove all the 'upfront' variables
- check to see if the hash was empty instead of setting a global flag after
it was filled
- populate the hash directly on the split instead of filling temp variables
from the spilt then placing them in the hash.. (what was I thinking?)
- move all the html into a sub and use type checking on the argument to
determine output. Never did that before so I learned something else new.
Problems
- This line... I understand what it does, but seems to get every line in my
input file ignored.. any ideas?
# next if $ROW =~ /^\s*?/; #<-- seems to kill even valid lines, example of
input lines below:
BellSouth User ^65.(80|81|82).(.*?)$,68.17.100.226,(.*?)bellsouth.net$ 901
0
SplitRock User (.*?)splitrock.net$ 901 0
Business Systems, Inc. 208.213.81.59 901 0
RoadRunner User (.*?)rr.com$ 901 0
Observations
- I wouldn't mind some input on better ways to handle the nested foreach
loop on the foreach $entry (keys %AddressAliases) and $bindings code. I'm
sure there's a better (more efficient) way to do this but I'm simply just
not aware of it and this would be a good spot to learn how to handle it
better.
- The regexp's for checking domains... this brings up a problem I've
researched with no solution. Is there any way to do range checking on the
fly in a regexp? For instance in this line:
BellSouth User ^65.(80|81|82).(.*?)$,68.17.100.226,(.*?)bellsouth.net$ 901
0
At one point the regexp is reduced in code from/to
if ($addresstoreplace =~ /$binding/) {
if ($addresstoreplace =~ /^65.(80|81|82).(.*?)$/) {
Given only that 'template' is there a way to check 80-82 without the or'ing?
I expect Larry will have a few pointers on this. I have some entries in the
flat file that are just putrid.. like this:
Level 3 User (.*?)level3.net$,^64.(152|153|154|155|156|157|158|159).(.*?)$
901 0
I've read a few threads that have led me to believe that I'm sunk... but I
just don't buy it.
BEGIN CODE
----------------------------------------------------------
#!/usr/bin/perl
use strict;no strict "refs";
my $PluginNeedAWStatsVersion="5.2";
my $PluginHooksFunctions="ReplaceAddress";
use vars qw/$addressaliasloaded %AddressAliases/;
sub Init_addressalias {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
debug("InitParams=$InitParams",1);
%AddressAliases=();
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
sub ReplaceAddress_addressalias {
my $addresstoreplace=$_[0];
unless (%AddressAliases) {
my $filetoload="$PluginDir/addressalias.txt";
local (*ADDRESSALIASFILE);
open(ADDRESSALIASFILE,"$filetoload") or error("Error: Couldn't open
AddressAlias file \"$filetoload\": $!");
my $rowcount = 0;
while (my $ROW = <ADDRESSALIASFILE>) {
chomp($ROW);
# next if $ROW =~ /^\s*?/; #<-- seems to kill even valid lines
next if $ROW =~ /^#/;
($AddressAliases{$rowcount}{'companyname'},
$AddressAliases{$rowcount}{'addresslist'},
$AddressAliases{$rowcount}{'website'},
$AddressAliases{$rowcount}{'classification'},
$AddressAliases{$rowcount}{'isclient'}) = split (/\t/, $ROW);
push
@{$AddressAliases{$rowcount}{'bindings'}},split(/,/,$AddressAliases{$rowcoun
t}{'addresslist'});
$rowcount++;
}
close ADDRESSALIASFILE;
debug("AddressAlias file loaded: ".(scalar keys %AddressAliases)."
aliases found.");
}
my $found = 0;
my $entry = '';
foreach $entry (keys %AddressAliases) {
$found = 0;
foreach my $binding(@{$AddressAliases{$entry}{'bindings'}}) {
# this checks against a hard coded regexp in $binding
if ($addresstoreplace =~ /$binding/) {
OutputHTML($AddressAliases{$entry});
$found = 1;
last;
}
}
last if ($found == 1);
}
unless($found) { OutputHTML($addresstoreplace) };
return 1;
}
sub OutputHTML{
my ($style, $class, $output, $linkstart, $linkend) = (qq~style="color:
#999999;font-weight:bold;size: 11px"~,'900','','','');
if (ref $_[0] eq 'HASH') {
($class, $output) = ($_[0]{'classification'},$_[0]{'companyname'});
if ($class eq '901') {
$style = qq~style="size: 11px; color: #999999;"~;
}else{
$style = qq~style="size: 11px"~;
$linkend = '</a>';
if ($_[0]{'isclient'} eq '1') {
$linkstart = qq~<a target="_blank" style="font-weight: bold;color:
#006633;" href="$_[0]{'website'}">~;
}else{
$linkstart = qq~<a target="_blank" style="font-weight: bold;color:
#FF0000;" href="http://www.google.com/search?q=$_[0]{'companyname'}">~;
}
}
}else{
$output = $_[0];
}
print qq~<font $style><img hspace="2"
src="$DirIcons/classification/$class.gif">~ . $linkstart . $output .
$linkend . qq~</font>~;
}
1; # Do not remove this line
------------------------------
Date: Thu, 23 Jan 2003 12:51:54 -0500
From: "Charles R. Thompson" <charlest@indysoft.com>
Subject: Re: Help With Nested Hash/Array Requested
Message-Id: <v30atri90s2rd9@corp.supernews.com>
Anno,
Thanks for the point. I've expanded on the regexp discussion in my newest
post.. you might take a look at that to see how I'm currently handling it
and dive in if you have any more input.
> > weeding through the barrage of *aol.com accounts, proxies located in
global
> > corporate domains and various ISPs hitting the server. I'm looking for
some
> > way to reorganize where I could do something like this (pseudo):
> >
> > $Addresses{'(.*?)aol.com$'}{1} = 'Aol User';
>
> Look at the module Tie::Hash::Approx. It may encapsulate nicely what
> you want to do. I doubt it will be particularly fast, however.
------------------------------
Date: 23 Jan 2003 17:56:10 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Help With Nested Hash/Array Requested
Message-Id: <b0pabq$4lr$1@mamenchi.zrz.TU-Berlin.DE>
Charles R. Thompson <charlest@indysoft.com> wrote in comp.lang.perl.misc:
[...]
> Problems
> - This line... I understand what it does, but seems to get every line in my
> input file ignored.. any ideas?
> # next if $ROW =~ /^\s*?/; #<-- seems to kill even valid lines, example of
> input lines below:
The "?" makes no sense in that pattern, it should be "$". Then it
matches blank lines. The way it is it matches any line, as you noted.
Anno
------------------------------
Date: Thu, 23 Jan 2003 13:04:11 -0500
From: "Charles R. Thompson" <charlest@indysoft.com>
Subject: Re: Help With Nested Hash/Array Requested
Message-Id: <v30bksepgmu88c@corp.supernews.com>
Huh... I missed that. I see how that is a problem though. I looked at that
original line and thought
"Match any line starting with a space and followed by 0 or more spaces"
> > # next if $ROW =~ /^\s*?/; #<-- seems to kill even valid lines
> The "?" makes no sense in that pattern, it should be "$". Then it
> matches blank lines. The way it is it matches any line, as you noted.
------------------------------
Date: Thu, 23 Jan 2003 10:20:52 -0800
From: "Mothra" <mothra@nowhereatall.com>
Subject: Is there a better way to check to see if a date lies within a certain range of dates
Message-Id: <3e3031b0$1@usenet.ugs.com>
Hi All,
I currently use the code snippet below to figure out if a date lies between
a certain range. What it does is convert the date to epoch and does
the compare. My questions is:
Is there a way to do this without converting to epoch? Does
someone have a better way to do this?
Thanks
Mothra
use Date::Manip;
use strict;
use warnings;
my $start_date = 'jan 04 2001';
my $end_date ='mar 21 2001';
while (<DATA>) {
my $test_date = UnixDate(ParseDate("$_"),"%s");
if ( ($test_date >= (UnixDate(ParseDate("$start_date"),"%s")))
&&
($test_date <= (UnixDate(ParseDate("$end_date"),"%s"))))
{
chop;
print "$_ is between!\n"
}
}
__DATA__
04/09/2002
05/10/2001
02/25/2001
02/01/2001
01/02/2001
------------------------------
Date: Thu, 23 Jan 2003 18:27:29 GMT
From: monkeys paw <fm_duendeBASURA@yahoo.com>
Subject: Re: Is there a better way to check to see if a date lies within a certain range of dates
Message-Id: <luWX9.11889$eM6.17288@rwcrnsc51.ops.asp.att.net>
Mothra wrote:
> Hi All,
>
> I currently use the code snippet below to figure out if a date lies
> between a certain range. What it does is convert the date to epoch and
> does the compare. My questions is:
> Is there a way to do this without converting to epoch? Does
> someone have a better way to do this?
>
> Thanks
>
> Mothra
>
>
>
> use Date::Manip;
> use strict;
> use warnings;
>
> my $start_date = 'jan 04 2001';
> my $end_date ='mar 21 2001';
>
> while (<DATA>) {
>
>
*> my $test_date = UnixDate(ParseDate("$_"),"%s");
*>
*> if ( ($test_date >= (UnixDate(ParseDate("$start_date"),"%s")))
*> &&
*> ($test_date <= (UnixDate(ParseDate("$end_date"),"%s"))))
*> {
This could be much cleaner but still uses Date::Manip :
if ( Date_Cmp($start_date, $test_date) < 0 &&
Date_Cmp($test_date, $end_date) < 0)
> chop;
> print "$_ is between!\n"
> }
>
>
> }
>
> __DATA__
> 04/09/2002
> 05/10/2001
> 02/25/2001
> 02/01/2001
> 01/02/2001
------------------------------
Date: Thu, 23 Jan 2003 18:38:03 GMT
From: monkeys paw <fm_duendeBASURA@yahoo.com>
Subject: Re: Is there a better way to check to see if a date lies within a certain range of dates
Message-Id: <fEWX9.11930$eM6.17274@rwcrnsc51.ops.asp.att.net>
monkeys paw wrote:
> Mothra wrote:
>
>> Hi All,
>>
>> I currently use the code snippet below to figure out if a date lies
>> between a certain range. What it does is convert the date to epoch and
>> does the compare. My questions is:
>> Is there a way to do this without converting to epoch? Does
>> someone have a better way to do this?
>>
>> Thanks
>>
>> Mothra
>>
>>
>>
>> use Date::Manip;
>> use strict;
>> use warnings;
>>
>> my $start_date = 'jan 04 2001';
>> my $end_date ='mar 21 2001';
>>
>> while (<DATA>) {
>>
>>
>
>
> *> my $test_date = UnixDate(ParseDate("$_"),"%s");
> *>
> *> if ( ($test_date >= (UnixDate(ParseDate("$start_date"),"%s")))
> *> &&
> *> ($test_date <= (UnixDate(ParseDate("$end_date"),"%s"))))
> *> {
>
> This could be much cleaner but still uses Date::Manip :
>
> if ( Date_Cmp($start_date, $test_date) < 0 &&
> Date_Cmp($test_date, $end_date) < 0)
SORRY...that should be
if ( Date_Cmp($start_date, $_) < 0 &&
Date_Cmp($_, $end_date) < 0)
>
>
>> chop;
>> print "$_ is between!\n"
>> }
>>
>>
>> }
>>
>> __DATA__
>> 04/09/2002
>> 05/10/2001
>> 02/25/2001
>> 02/01/2001
>> 01/02/2001
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
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.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.
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 V10 Issue 4455
***************************************