[24108] in Perl-Users-Digest
Perl-Users Digest, Issue: 6302 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Mar 25 18:05:55 2004
Date: Thu, 25 Mar 2004 15:05:07 -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, 25 Mar 2004 Volume: 10 Number: 6302
Today's topics:
Database style hash? (dmb000006)
Re: Database style hash? (Anno Siegel)
Re: dollar sign and spaces from a string <MrReallyVeryNice.NOVIRUS@NoSpam.yahoo.com>
Re: how to check if a table already exists? <s.patterson@freeuk.com>
Re: how to check if a table already exists? <bdu@iastate.edu>
How to interpolate string containing a variable <mark.gaber@obs.unige.ch>
Re: I want to scanf, dammit! <mitia.nospam@northwestern.edu.invalid>
Re: I want to scanf, dammit! (Anno Siegel)
Re: I want to scanf, dammit! <ittyspam@yahoo.com>
Re: I want to scanf, dammit! <ittyspam@yahoo.com>
Re: I want to scanf, dammit! <tassilo.parseval@rwth-aachen.de>
match pattern with $ failed (nickelstat)
Re: Per Script Beginner Advice (SWREG) <1usa@llenroc.ude>
Re: problem with index not matching string exactly (Anno Siegel)
Re: Puzzling Socket::inet_ntoa problem <krahnj@acm.org>
Re: q: regex: parse <length><value>? <"dbwood at acm dot org">
SCALAR(0x82dea94) <todd@asgweb.net>
Re: SCALAR(0x82dea94) (Anno Siegel)
Re: SCALAR(0x82dea94) <1usa@llenroc.ude>
Re: Switching .... <tore@aursand.no>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 25 Mar 2004 13:11:52 -0800
From: dmb000006@hotmail.com (dmb000006)
Subject: Database style hash?
Message-Id: <934a5d96.0403251311.7b5d214f@posting.google.com>
Hello,
I have a database style data structure, each record has several
fields.
I would like to create a nested data structure that would let me
'query' the data on the value of certain fields.
I did this by making the following type of data...
Sample PDB data...
ATOM 72 C ARG L 9 41.592 23.248 98.505 1.00 34.28
C
ATOM 73 O ARG L 9 42.467 23.303 97.634 1.00 33.66
O
ATOM 74 CB ARG L 9 40.542 25.445 99.063 1.00 32.51
C
ATOM 75 CG ARG L 9 40.415 26.641 99.989 1.00 30.92
C
ATOM 76 CD ARG L 9 39.771 27.823 99.291 0.00 47.64
C
ATOM 77 NE ARG L 9 38.331 27.672 99.123 0.00 67.84
N
package PDB;
our $pdbTemplate
= 'x6 A5 x1 A4 A1 A3 x1 A1 A4 A1 x3 A8 A8 A8 A6 A6 x6';
our @pdbDescriptive
= qw( serial name altLoc resName chainID resSeq iCode x y z
occupancy tempFactor segID element charge );
our @pdbDataIndex
= qw( serial name altLoc resName chainID resSeq iCode );
sub readPDB {
my $pdb = shift;
unless (ref($pdb) eq "GLOB"){
$pdb = openPDB($pdb);
}
# Data to return
my %pdbData;
while ( <$pdb> ){
next unless /^ATOM|^HETATM/o;
# Parse PDB file (see $pdbTemplate above)
my @atom = unpack( $pdbTemplate, $_ );
# Trim each value.
foreach ( @atom ){ s/^\s+// };
# Must be a better way? (to make a HASH).
my %atom = map { $pdbDescriptive[$_], $atom[$_] } ( 0..$#atom );
# Build up quite a complex data structure.
foreach (@pdbDataIndex){
push @{$pdbData{$_}{$atom{$_}}}, \%atom;
}
push @{$pdbData{'data'}}, \%atom;
}
return \%pdbData;
}
__END__
This lets me say...
use PDB;
my $data # Special data structure!
= readPDB( $pdb ); # Would be good to use Fields;
my @chainIDs # Lookup 'chain' entries
= sort keys %{ $data->{'chainID'} };
foreach my $chainID ( @chainIDs ){
my @atoms # Use 'chain' entry to get at underlying
atoms.
= @{ $data->{'chainID'}->{$chainID} };
print "$chain\t". scalar(@atoms). "\n";
}
__END__
But I would like to go one step further and for each chain return each
residue, or for each residue return each chain etc... (i.e. recursive
data structure).
How can I do this?
------------------------------
Date: 25 Mar 2004 21:52:28 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Database style hash?
Message-Id: <c3vkas$f9f$1@mamenchi.zrz.TU-Berlin.DE>
dmb000006 <dmb000006@hotmail.com> wrote in comp.lang.perl.misc:
> Hello,
>
> I have a database style data structure, each record has several
> fields.
>
> I would like to create a nested data structure that would let me
> 'query' the data on the value of certain fields.
>
> I did this by making the following type of data...
[snip most code]
> # Parse PDB file (see $pdbTemplate above)
> my @atom = unpack( $pdbTemplate, $_ );
>
> # Trim each value.
> foreach ( @atom ){ s/^\s+// };
>
> # Must be a better way? (to make a HASH).
> my %atom = map { $pdbDescriptive[$_], $atom[$_] } ( 0..$#atom );
This can indeed be streamlined. You don't really need the @atom array.
my %atom;
@atom{ @pdbDescriptive} = unpack( $pdbTemplate, $_ );
s/^\s+// for values %atom;
That's it.
[...]
> But I would like to go one step further and for each chain return each
> residue, or for each residue return each chain etc... (i.e. recursive
> data structure).
Sorry, I don't follow you. Too much shop talk of chains and residues
for someone not acquainted with the problem area.
Anno
------------------------------
Date: Thu, 25 Mar 2004 14:43:33 -0800
From: "MrReallyVeryNice" <MrReallyVeryNice.NOVIRUS@NoSpam.yahoo.com>
Subject: Re: dollar sign and spaces from a string
Message-Id: <78qdnfB-srBR_v7dRVn-gg@comcast.com>
> I don't understand...?
Could James Willmore be making a reference to the following post?
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&c2coff=1
&frame=right&th=76bd13468e38d70b&seekm=pan.2004.03.20.22.46.32.400862%40
remove.adelphia.net#link13
(read the entire thread or at least the post from Gnari in the same
thread)
Our guidelines at
http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
reference the Netiquette Guidelines
(http://asg.web.cmu.edu/rfc/rfc1855.html). One could infer
(rightly or wrongly?) that the URL means the Netiquette Guidelines are
'by reference' also part of our guidelines. Assuming that the above
assumption
is correct, one could also assume that the following is also part of our
guidelines (see page 9):
- If you should find yourself in a disagreement with one person,
make your responses to each other via mail rather than continue to
send messages to the list or the group. If you are debating a
point on which the group might have some interest, you may
summarize for them later.
Of course the following would apply to any of my future postings to this
thread:
- Don't get involved in flame wars. Neither post nor respond
to incendiary material.
Therefore no matter the type of response that this post might generate, I
will
keep quiet.
Mr Really Very Nice
:)
------------------------------
Date: 25 Mar 2004 19:30:30 GMT
From: Stephen Patterson <s.patterson@freeuk.com>
Subject: Re: how to check if a table already exists?
Message-Id: <slrnc66cqm.rn.s.patterson@bloodnok.localdomain>
On Thu, 25 Mar 2004 09:34:13 -0600, Bing Du wrote:
> Is there an easy way to check if a table already exists before creating
> a new table? Do I have to do 'show tables' and then check if the target
> table exists in the list of tables returned?
In DBI, you should be able to do @tables = $dbh->tables();
--
Stephen Patterson http://patter.mine.nu/
steveSPAM@.patter.mine.nu remove SPAM to reply
Linux Counter No: 142831 GPG Public key: 252B8B37
Caution: breathing may be hazardous to your health.
------------------------------
Date: Thu, 25 Mar 2004 14:23:40 -0600
From: Bing Du <bdu@iastate.edu>
To: Stephen Patterson <s.patterson@freeuk.com>
Subject: Re: how to check if a table already exists?
Message-Id: <40633FCC.2020300@iastate.edu>
Great! This is kind of what I was asking for. Thanks for the heads-up,
Stephen.
Bing
Stephen Patterson wrote:
> On Thu, 25 Mar 2004 09:34:13 -0600, Bing Du wrote:
>
>>Is there an easy way to check if a table already exists before creating
>>a new table? Do I have to do 'show tables' and then check if the target
>>table exists in the list of tables returned?
>
>
> In DBI, you should be able to do @tables = $dbh->tables();
>
------------------------------
Date: Thu, 25 Mar 2004 22:58:29 +0100
From: Mark Gaber <mark.gaber@obs.unige.ch>
Subject: How to interpolate string containing a variable
Message-Id: <40635605.C81F56B4@obs.unige.ch>
Hello,
I have a string variable which contains a command to be executed using
backticks ``. The command involves variables and so has to be
interpolated. For example, the following does a touch of /tmp/zzTest:
#!/usr/bin/perl
$filename = "/tmp/zzTest";
$strCmd = "`touch \$filename`";
print "strCmd is $strCmd \n";
eval ${\ $strCmd };
exit;
The output is not interpolated though:
strCmd is `touch $filename`
strCmd is `touch /tmp/zzTest` <----- how do I get it to show this
line instead??
Thank you,
Mark
------------------------------
Date: 25 Mar 2004 19:15:49 GMT
From: Dmitry Epstein <mitia.nospam@northwestern.edu.invalid>
Subject: Re: I want to scanf, dammit!
Message-Id: <Xns94B7879B0C0D5mitianorthwesternedu@63.218.45.22>
Malte Ubl <m@lteubl.de> wrote in news:c3u793$76k$1@news.dtag.de:
> Dmitry Epstein wrote:
>> Using something like scanf or the C++ stream input operator,
>> the solution is ludicrously simple:
>
>> So there.
>
> http://search.cpan.org/search?query=scanf&mode=all
>
> Does that help?
String::scanf is indeed nearly useless, as the sages say. It does
not extract from the input stream directly, so I still need to read
a line or the entire file first. In that case I may as well use
split or regex.
> If it doesnt, just use Inline::C.
Er.. what's that?
--
Dmitry Epstein
Northwestern University, Evanston, IL. USA
mitia(at)northwestern(dot)edu
------------------------------
Date: 25 Mar 2004 19:30:22 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: I want to scanf, dammit!
Message-Id: <c3vc0e$a0d$1@mamenchi.zrz.TU-Berlin.DE>
Dmitry Epstein <mitia.nospam@northwestern.edu.invalid> wrote in comp.lang.perl.misc:
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote in
> news:c3u5gn$elj$1@mamenchi.zrz.TU-Berlin.DE:
> > Dmitry Epstein <mitia.nospam@northwestern.edu.invalid> wrote
> > in comp.lang.perl.misc:
[find the nth number in a file]
> > my $n = 500;
> > my @line;
> > while ( <DATA> ) { last if ( $n -= @line = split) < 0 }
> > print "$line[ $n]\n";
> >
>
> I think your $n is negative by the time you get to the last
> statement, no?
Yes, it is, in exactly the right way :) Look for "negative" in perldata.
Anno
------------------------------
Date: Thu, 25 Mar 2004 14:52:05 -0500
From: Paul Lalli <ittyspam@yahoo.com>
Subject: Re: I want to scanf, dammit!
Message-Id: <20040325145054.K21521@dishwasher.cs.rpi.edu>
On Thu, 25 Mar 2004, Dmitry Epstein wrote:
> I know this has been asked before, mostly by novice percolytes (is
> that what you call Perl adherents?), but the sages just replied:
> scanf sucks, we don't need it. Well, here is a real-life situation
> that I have to deal with quite frequently. See if you can suggest
> an acceptable solution using the all-mighty pattern search.
>
> I have a file with floats separated by spaces and newlines. There
> can be several numbers per line, but I don't know and don't care
> about exactly how they are written because that has no relation to
> the logic of the problem. Suppose the file contains 2500 numbers
> and I need to read the first 500, or better yet, read just the
> number #500. This number can be in the middle of a line, for all I
> know.
>
use strict;
use warnings;
use File::Stream;
open my $fh, $ARGV[0] or die "Cannot open $ARGV[0]: $!";
my $fs = File::Stream->new($fh);
local $/ = qr/\s+/;
my $i;
while (my $word = <$fs>){
next if ++$i != 500;
$word =~ s|$/||g;
print "$word\n";
}
Paul Lalli
------------------------------
Date: Thu, 25 Mar 2004 14:55:31 -0500
From: Paul Lalli <ittyspam@yahoo.com>
Subject: Re: I want to scanf, dammit!
Message-Id: <20040325145317.G21521@dishwasher.cs.rpi.edu>
On Thu, 25 Mar 2004, Paul Lalli wrote:
> On Thu, 25 Mar 2004, Dmitry Epstein wrote:
>
> > I have a file with floats separated by spaces and newlines. There
> > can be several numbers per line, but I don't know and don't care
> > about exactly how they are written because that has no relation to
> > the logic of the problem. Suppose the file contains 2500 numbers
> > and I need to read the first 500, or better yet, read just the
> > number #500. This number can be in the middle of a line, for all I
> > know.
> >
>
> use strict;
> use warnings;
> use File::Stream;
>
> open my $fh, $ARGV[0] or die "Cannot open $ARGV[0]: $!";
> my $fs = File::Stream->new($fh);
> local $/ = qr/\s+/;
>
> my $i;
> while (my $word = <$fs>){
> next if ++$i != 500;
> $word =~ s|$/||g;
> print "$word\n";
> }
>
>
> Paul Lalli
>
Bah. Sent the wrong version. Switch that while loop to:
my ($i, $word);
while ($word = <$fs>){
last if ++$i == 500;
}
$word =~ s|$/||g;
print "$word\n";
Paul Lalli
------------------------------
Date: 25 Mar 2004 21:33:08 GMT
From: "Tassilo v. Parseval" <tassilo.parseval@rwth-aachen.de>
Subject: Re: I want to scanf, dammit!
Message-Id: <c3vj6k$5c$1@nets3.rz.RWTH-Aachen.DE>
Also sprach Dmitry Epstein:
> Malte Ubl <m@lteubl.de> wrote in news:c3u793$76k$1@news.dtag.de:
>> Dmitry Epstein wrote:
>>> Using something like scanf or the C++ stream input operator,
>>> the solution is ludicrously simple:
>>
>>> So there.
>>
>> http://search.cpan.org/search?query=scanf&mode=all
>>
>> Does that help?
>
> String::scanf is indeed nearly useless, as the sages say. It does
> not extract from the input stream directly, so I still need to read
> a line or the entire file first. In that case I may as well use
> split or regex.
>
>> If it doesnt, just use Inline::C.
>
> Er.. what's that?
Inline::C allows you to embed C code into your Perl script. Here's a
super-simplistic scanner on top of fscanf() available from Perl:
#! /usr/bin/perl -w
use strict;
use Inline Config => BUILD_NOISY => 1;
use Inline 'C';
my ($a, $b) = my_scanf(\*STDIN, "%f %i");
print "float: $a\n";
print "int: $b\n";
__END__
__C__
void my_scanf (PerlIO *io, char *fmt) {
FILE *f = PerlIO_findFILE(io);
int n = 0;
double d;
int i;
Inline_Stack_Vars;
Inline_Stack_Reset;
while (*fmt) {
if (*fmt++ == '%') {
switch(*fmt) {
case 'f':
fscanf(f, "%lf", &d);
Inline_Stack_Push(sv_2mortal(newSVnv(d)));
n++;
break;
case 'i':
fscanf(f, "%i", &i);
Inline_Stack_Push(sv_2mortal(newSViv(i)));
n++;
}
}
}
Inline_Stack_Done;
Inline_Stack_Return(n);
}
The problem with scanf-alike functions is that they use variadic
arguments. That means, you have to write your own little parser for the
format string. The above only recognizes '%f' for doubles and '%i' for
integers. It shouldn't be too hard to implement a more generous subset
of a scanf-format.
Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
------------------------------
Date: 25 Mar 2004 14:51:11 -0800
From: nickelstat@sbcglobal.net (nickelstat)
Subject: match pattern with $ failed
Message-Id: <21160ba4.0403251451.43c2584@posting.google.com>
Here is an example that failed.
==================================
$s1 = $s2 = '$abc'; # identical value with $ in it
if ($s1 eq $s2) {
print qq%"$s1" (s1) EQUALS "$s2" (s2)\n%;
} else {
print qq%"$s1" (s1) NOT = "$s2" (s2)\n%;
}
#if ($s1 =~ /$s2/) { # same bad result
if ($s1 =~ m'$s2') { # how do I tell Perl to not expand $s2?
print qq%"\$s1" contains the string "$s2"\n%;
} else {
print qq%"\$s1" does NOT contains the string "$s2"\n%;
}
======================================
Output:
"$abc" (s1) EQUALS "$abc" (s2)
"$s1" does NOT contains the string "$abc"
How do I make it recognize that '$abc' is in $s1?
Thanks
even though the
------------------------------
Date: 25 Mar 2004 21:03:49 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude>
Subject: Re: Per Script Beginner Advice (SWREG)
Message-Id: <Xns94B7A3685E595asu1cornelledu@132.236.56.8>
James Willmore <jwillmore@remove.adelphia.net> wrote in
news:pan.2004.03.25.14.04.53.4864@remove.adelphia.net:
> Just an aside, this link *may* be helpful for the OP:
> http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=e01608
> 15.0210261950.e9fa592%40posting.google.com
>
> Someone did share how to make the link shorter, but for the life of me
> I don't remember where I put that helpful hint :-(
http://tinyurl.com
For example, you can visit the link above using:
http://tinyurl.com/yrnoj
--
A. Sinan Unur
1usa@llenroc.ude (reverse each component for email address)
------------------------------
Date: 25 Mar 2004 19:42:29 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: problem with index not matching string exactly
Message-Id: <c3vcn5$a0d$2@mamenchi.zrz.TU-Berlin.DE>
G <bay_dar@yahoo.com> wrote in comp.lang.perl.misc:
> I'm looping through a sales_file looking for matches to $code. Note
> the file contains no spaces after the "|". Duplicates are allowed on
> different lines, but not the same line. The file has a number of
> entries such as the following (sample $sales_file):
>
> sales item aaa|543,m423a
> sales item bbb|m423,543 #Note how code 543 is on the 1st 2ndline.
> sales item ccc|m423b
> sales item ddd|423,423b,m523,652
>
> - Also note we have entires of m423, m423a and m423b. The problem with
So, are these equivalent or not? You're not saying.
> my code, is that it matches the $entered_code of m423 to m423, m423a,
> and m423b but I want it to only match up to m423. Of course 423 should
> only match up to 423 and so on. Anyone have a suggestion to fix this?
>
> Here is the code segment:
>
> open FILE, "<$sales_file" or die "could not open '$sales_file' $!";
> while (<FILE>) {
> chomp;
> my ($sales_item, $code) = split /\|/;
> my @code = split /,/, $exits;
>
> if (index($code, $entered_code) != -1) {
> $list .="<ul>" if !($list);
> $list .= "<li><p>$sales_item</li>";
> }
>
> }
Your code and your verbal description don't agree. Don't you want
to split $code in the second split? If not, what's in $exit?
In any case, what's in $entered_code?
Your description leaves open too many possibilities. What, exactly, are
the "codes" you speak of, and what are the strings you want to compare
them too?
Anno
------------------------------
Date: Thu, 25 Mar 2004 23:01:14 GMT
From: "John W. Krahn" <krahnj@acm.org>
Subject: Re: Puzzling Socket::inet_ntoa problem
Message-Id: <4063645A.5931E5F6@acm.org>
axel@white-eagle.co.uk wrote:
>
> Anno Siegel <anno4000@lublin.zrz.tu-berlin.de> wrote:
> > > I am trying to figure out why saving the result of gethostbyname in a
> > > variable and then using inet_ntoa on that variable works fine, whereas
> > > trying to pass the result directly to inet_ntoa bombs out. I can't find
> > > anything in the documentation.
>
> > Context. The get* functions return different results in list and scalar
> > context, as the doc clearly states. Try (untested)
>
> > inet_ntoa(scalar gethostbyname($ip))
>
> Thanks, that solves the mystery.
Or you can just use the host name directly:
use Socket;
$ip = 'www.yahoo.com';
$temp = inet_ntoa( inet_aton( $ip ) );
print $temp, "\n";
John
--
use Perl;
program
fulfillment
------------------------------
Date: Thu, 25 Mar 2004 15:59:59 -0500
From: "dbwood at acm dot org" <"dbwood at acm dot org">
Subject: Re: q: regex: parse <length><value>?
Message-Id: <ZuWdnV8-xIjH1f7dRVn-hQ@comcast.com>
Tassilo v. Parseval wrote:
> Also sprach dbwood at acm dot org:
>
>
>>Is there a regular expression that will extract a field value when the
>>field has a length indicator describing how many characters are in the
>>field? e.g. 7abcd123 refers to the value abcd123 and 3abcd123 refers to abc
>>
>>I know that unpack() is probably a better way, but the only regular
>>expression we can figure out is to use something like the extended
>>regular espression (??{ code }) as in (concept only):
>>
>>qr/(\d+)(??{ qr/.{$1}/ } )/
>>
>>and I think using unpack() twice is faster.
>
>
> Why using it twice? This can be done with one unpack:
>
> my $field = unpack "A/A", "3abcd123";
>
> Tassilo
Thanks! Exactly. How about a regular expression?
Dave
------------------------------
Date: Thu, 25 Mar 2004 12:42:55 -0700
From: Todd Anderson <todd@asgweb.net>
Subject: SCALAR(0x82dea94)
Message-Id: <40633639.5608CDF8@asgweb.net>
Hello,
I posted this before and respondents wanted more code to help decipher
it. So I'm posting again with code below.
I have a script that is run by crontab. It Opens $user_file (flat file)
and checks for accounts with current date and charges the users card if
it's 30 days old. It also sends a reminder to those who are on the 30
day free trial. Sometimes it puts this... SCALAR(0x82dea94) or
something similar at the beginning of the a line in the $user_file. The
scipt only processes 20 lines at a time to avoid server time out.
Thanks in advance for your help.
sub billing_engine {
$e_number = "-1";
open (USERS, "$user_file") || &billerror
("$user_file Billing Notice" );
flock(USERS, 2);
while (<USERS>)
{
$line = $_;
chomp $line;
@fields = split (/\|/, $line);
@line =$line;
foreach $jiggy(@line){
$e_number++;
if (($start eq "$e_number")..($end eq "$e_number")){
$namelist .="$fields[1]\n";
$yes_row_count++;
($dbmonth,$dbday,$dbyear) = split (/\//, $fields[$field_for_update]);
$julian_day = &jday($dbmonth,$dbday,$dbyear);
($today_month,$today_day,$today_year) = split (/\//, &get_date);
$today = &jday($today_month,$today_day,$today_year);
$updated_days_ago = ($today - $julian_day);
if($fields[$field_for_account_status] eq "Ok"){
$current_row .= "$line";
@chargerow = $current_row;
foreach $customer (@chargerow){
if ($updated_days_ago >= "30"){
$auth_count++;
&auto_send_to_authorizenet;
if($declined){
$fields[$field_for_account_status] = "Ten_Days_Left";
$new_current_row .= join('|' => @fields) . "\n";
$email_user = $fields[$field_for_email];
&declined_email;
&admin_declined_email;
$email_user = "";
}
else{ #not declined
$fields[$field_for_account_status] = "Ok";
$fields[$field_for_update] = "$current_date";
$new_current_row .= join('|' => @fields) . "\n";
$email_user = $fields[$field_for_email];
&write_log;
&account_paid_email;
&admin_account_paid_email;
$email_user = "";
}#else not declined
}# if 30 days old
#save all the ones not 30 days old yet
else{ $new_current_row .= "$line\n";}
}# foreach chargerow
$new_current_row = "$new_current_row";
}#status Ok
###########################################
else {#not Ok
$bill_row .= "$line";
@bill_row = $bill_row;
foreach $bill (@bill_row ){
#This is what we do with all the people on 30 day trial
$bill_row_count++;
################
if($fields[$field_for_account_status] eq "One_Day_Left"){
$One_bill_row_count++;
$Thirty_bill_row_count++;
$fields[$field_for_account_status] = "Delete";
$Thirty_bill_row .= join('|' => @fields) . "\n";
}
#################
elsif($fields[$field_for_account_status] eq "Two_Days_Left"){
$Thirty_bill_row_count++;
$fields[$field_for_account_status] = "One_Day_Left";
$Thirty_bill_row .= join('|' => @fields) . "\n";
$email_user = $fields[$field_for_email];
&thirty_day_email;
$email_user = "";
}
#etc to 30-day-trial
#################
elsif($fields[$field_for_account_status] eq "30-Day-Trial"){
$Thirty_bill_row_count++;
$fields[$field_for_account_status] = "TwentyNine_Days_Left";
$Thirty_bill_row .= join('|' => @fields) . "\n";
$email_user = $fields[$field_for_email];
&thirty_day_email;
$email_user = "";
}
#################
elsif($fields[$field_for_account_status] eq "Donated"){
$Thirty_bill_row_count++;
$fields[$field_for_account_status] = "Donated";
$Thirty_bill_row .= join('|' => @fields) . "\n";
$email_user = $fields[$field_for_email];
$email_user = "";
}
#################
else{
$Leftover_bill_row_count++;
$Thirty_bill_row_count++;
$fields[$field_for_account_status] = "LeftOver";
$Thirty_bill_row .= join('|' => @fields) . "\n";
}
#################
}#foreach $bill
}#else
}#@billingnumber
else{ $hold_row_count++;
$hold_row .="$line\n"; }
}#jiggy
}#while
flock(USERS, 8);
close (USERS);
open (USERS, ">$user_file") || &billerror("$user_file Billing Notice");
flock(USERS, 2);
print USERS "$hold_row";
print USERS "$new_current_row";
print USERS "$Thirty_bill_row";
flock(USERS, 8);
close (USERS);
############
}#billing engine
------------------------------
Date: 25 Mar 2004 20:28:25 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: SCALAR(0x82dea94)
Message-Id: <c3vfd9$cii$1@mamenchi.zrz.TU-Berlin.DE>
Todd Anderson <todd@asgweb.net> wrote in comp.lang.perl.misc:
> Hello,
> I posted this before and respondents wanted more code to help decipher
> it. So I'm posting again with code below.
> I have a script that is run by crontab. It Opens $user_file (flat file)
> and checks for accounts with current date and charges the users card if
> it's 30 days old. It also sends a reminder to those who are on the 30
> day free trial. Sometimes it puts this... SCALAR(0x82dea94) or
> something similar at the beginning of the a line in the $user_file. The
> scipt only processes 20 lines at a time to avoid server time out.
> Thanks in advance for your help.
[167 lines of code snipped]
That's too much code to read, especially since it doesn't help
diagnose the problem.
Why? Because the three variables ($hold_row, $new_current_row,
$Thirty_bill_row) that are printed to the file in question are global
to the subroutine, and never reset. These crucial variables are only
ever accessed via ".=". All bets are off what they might contain before
the sub is entered.
The code shown doesn't show the most obvious things that could create
a scalar ref by accident, so it seems likely that the error is somewhere
in the environment.
This is a good demonstration of the evil of global variables with
indistinct scope. Who knows where these variables are touched before,
probably by accident in code that has no business touching them, in any
case inappropriately. It's a debugging nightmare.
And the sub is *much* too long. It ought to be decomposed in five to
ten smaller ones.
Anno
------------------------------
Date: 25 Mar 2004 20:29:17 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude>
Subject: Re: SCALAR(0x82dea94)
Message-Id: <Xns94B79D8D89598asu1cornelledu@132.236.56.8>
Todd Anderson <todd@asgweb.net> wrote in news:40633639.5608CDF8@asgweb.net:
> Hello,
> I posted this before and respondents wanted more code to help decipher
> it. So I'm posting again with code below.
Your code is pretty hard to read. Have you tried indenting it properly? You
also have not provided code we can run.
> I have a script that is run by crontab. It Opens $user_file (flat file)
> and checks for accounts with current date and charges the users card if
> it's 30 days old. It also sends a reminder to those who are on the 30
> day free trial. Sometimes it puts this... SCALAR(0x82dea94) or
> something similar at the beginning of the a line in the $user_file. The
> scipt only processes 20 lines at a time to avoid server time out.
> sub billing_engine {
> $e_number = "-1";
huh? Is $e_number a global variable? If not, scope it properly using my.
And why quote it?
> open (USERS, "$user_file") || &billerror
> ("$user_file Billing Notice" );
There is no point in putting that ampersand in front of bilerror. Please
read perldoc perlsub to see what that actually does.
I will suggest:
open my $users, '<', $user_file or billerror("Error opening $user_file:
$!");
Also, where did that $user_file come from? Is it an argument to the sub?
Shouldn't it be?
> flock(USERS, 2);
Avoid magic numbers:
use Fcntl ':flock';
flock $users, LOCK_EX;
> while (<USERS>)
> {
> $line = $_;
> chomp $line;
> @fields = split (/\|/, $line);
>
> @line =$line;
All I can say to this is WTF?!
while(<$users>) {
chomp;
my @fields = split /\|/;
...
> foreach $jiggy(@line){
Isn't this a pretty useless loop?
> $e_number++;
sooo ... $e_number is numeric after all.
> if (($start eq "$e_number")..($end eq "$e_number")){
Where did $start and $end come from?
> $namelist .="$fields[1]\n";
> $yes_row_count++;
I am lost ... I give up.
--
A. Sinan Unur
1usa@llenroc.ude (reverse each component for email address)
------------------------------
Date: Thu, 25 Mar 2004 22:34:04 +0100
From: Tore Aursand <tore@aursand.no>
Subject: Re: Switching ....
Message-Id: <pan.2004.03.25.21.34.02.896843@aursand.no>
On Thu, 25 Mar 2004 18:18:55 +0000, Anno Siegel wrote:
>>> "Getting rusty" in one language while you are using another is a
>>> protective mechanism. You don't *want* concepts and structures from
>>> another language to pop up in your head, so you block them.
>> I don't think I agree on that one; I think it's _useful_ to know to
>> solve the same problem in multiple programming languages. Knowing one
>> language sometimes makes you better in another language.
>>
>> My primary programming language is Perl, but I'm also programming in
>> C#. There have been many times where I have a C# problem and solves it
>> very clever (IMO, of course) by thinking on how I would've done it in
>> Perl.
> Yes, but that applies to the design part of programming. When you're
> actually coding, lapsing into another language is an error.
Of course. I was thinking only of the design part. The $-sign is quite
often used in my C# programming. I guess I'll get rid of it by the end of
the year. :)
--
Tore Aursand <tore@aursand.no>
"Scientists are complaining that the new "Dinosaur" movie shows
dinosaurs with lemurs, who didn't evolve for another million years.
They're afraid the movie will give kids a mistaken impression. What
about the fact that the dinosaurs are singing and dancing?" -- Jay
Leno
------------------------------
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.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
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 6302
***************************************