[24558] in Perl-Users-Digest
Perl-Users Digest, Issue: 6736 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Jun 27 11:05:40 2004
Date: Sun, 27 Jun 2004 08:05:04 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 27 Jun 2004 Volume: 10 Number: 6736
Today's topics:
Re: Correct file locking techniques <usenet@morrow.me.uk>
Re: error logs... <ebohlman@omsdev.com>
Re: Odd quick writing data to a file <ducott@hotmail.com>
Re: Odd quick writing data to a file <usenet@morrow.me.uk>
Re: Printing a hash question <ebohlman@omsdev.com>
Re: repeated calculations everyday <usenet@morrow.me.uk>
Re: Splitting a file (J. Romano)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sun, 27 Jun 2004 14:54:00 +0100
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Correct file locking techniques
Message-Id: <o403r1-636.ln1@mauzo.dyndns.org>
Quoth see@sig.invalid:
> Robert TV wrote:
>
> > Hi, I am asking foir advice on which form of code i've written below is the
> > correct and safe way to lock a file. I've done some reading on" use Fcntl
>
> I have found that the most portable and least hassle way to lock files
> is to use a lock file. This is a file which is used exclusively for the
> purpose of establishing a lock -- it can be empty, or have any contents
> you want, but the data in the lock file would be unused and unimportant.
> This technique is particularly useful when doing stuff which is a bit
> out of the ordinary, such as locking DBM-type files to which you wish to
> tie a hash, for example.
You can still perfectly well take a flock lock on the DBM file.
> If you want to write a file, open the lock file for write (that will, at
> least on some systems, wipe out the contents of the lock file), then
> establish an exclusive lock on it.
The usual reason for using a lockfile is to avoid making locking calls
altogether... a call to sysopen with O_CREAT | O_EXCL will atomically
test-and-create the named file, so there is no need to then lock it.
> To the best of my knowledge, that works flawlessly on at least local
> files on every OS that supports locking (that, by the way, rules out
> Windoze 95/98/98SE).
However, I think that win98 *does* support O_EXCL properly, so that
method will work.
> However, you should carefully and thoroughly read
> everything your OS has to say about file locking, particularly if you
> are considering locking files accessed via a network.
Yes. I belive most network filesystems do it properly; the exception is
NFSv2, and there are (at least on linux) instructions in open(2) for how
to safely lock files over NFS.
> I find it convenient to write a couple of subs to do the locking, like
> [untested]:
>
> sub lockex{
> open LOCK,">lockfile.txt"
Note that if you choose to put any useful information in the lockfile
(it is common to put the pid and possibly the hostname of the process
which created the lock, so later processes can check if you still exist)
you would need to sysopen it with O_RDWR | O_CREAT to ensure you didn't
destroy info about someone else's lock.
> or die "Oops, couldn't open lockfile.txt for write, $!";
> flock(LOCK,LOCK_EX)
> or die "flock bombed out in lockex, $!";
> }
> sub locksh{
> open LOCK,"lockfile.txt"
> or die "Oops, couldn't open lockfile.txt for read, $!";
> flock(LOCK,LOCK_SH)
> or die "flock bombed out in locksh, $!";
> }
> sub unlock{
> close LOCK or die "Oops, couldn't close lockfile.txt, $!";
> }
Yuck! What happens if you call this twice, for different files? You'll
implicitly close the global FH and destroy your lock. Try
{
my %locks;
sub lock {
my ($file, $type) = shift;
open $locks{$file}, '>', "$file.lock"
or die "can't create $file.lock: $!";
flock $locks{$file}, $type
or die "can't get lock on $file.lock: $!";
}
sub unlock {
close $locks{$_[0]};
}
}
Ben
--
Musica Dei donum optimi, trahit homines, trahit deos. |
Musica truces molit animos, tristesque mentes erigit. | ben@morrow.me.uk
Musica vel ipsas arbores et horridas movet feras. |
------------------------------
Date: 27 Jun 2004 05:50:21 GMT
From: Eric Bohlman <ebohlman@omsdev.com>
Subject: Re: error logs...
Message-Id: <Xns951594637A2Bebohlmanomsdevcom@130.133.1.4>
"John ©" <johnjcarbone@nospam.hotmail.com> wrote in
news:6L8Dc.3299$Av3.1096@nwrdny01.gnilink.net:
> "Brian McCauley" <nobull@mail.com> wrote in message
> news:u9zn6rwl8y.fsf@wcl-l.bham.ac.uk...
>
>> Yes, I must confess, that I tend to assume that people who come here
>> and behave this way are Americans.
>
> 'behave this way'? Exactly what way was I behaving... all I did was
> ask for people not to be rude. Is that such a crime?
But you're interpreting the customs of the foreign culture into which
you've inserted yourself as "rudeness," and asking foreigners to change
their customs simply to accommodate you is what's rude (it's the basis of
the "ugly American" stereotype; note that I'm American myself).
For example, in most European societies people will *not* ordinarily
address a person by his first name unless they have a *very* close
(familial, intimate, or long-term friendship) relationship with him.
Americans visiting Europe often misinterpret that as "rudeness" or
"snobbery." But it would be rude and snobbish to complain about that.
------------------------------
Date: Sun, 27 Jun 2004 05:36:40 GMT
From: "Robert TV" <ducott@hotmail.com>
Subject: Re: Odd quick writing data to a file
Message-Id: <I1tDc.903293$oR5.437803@pd7tw3no>
I have found my problem. it has to do with the file extension oddly enough.
To view the newly created file, I log into the server with my ftp program. I
then double click it to execute the programs "view file" command. It opens
in Windows Notepad. When viewing the files as an .inc extension, all data is
on the same line. If I rename to .txt and reopen, the data is on separate
lines ... so it appears that Notepad was the culprit.
Robert
"Bob Walton" <invalid-email@rochester.rr.com> wrote in message
news:40DE35B8.2020907@rochester.rr.com...
> Robert TV wrote:
>
> > I seem to be experiencing something odd when writing data to a file ...
I
> > say because I have not had a problem like this before. I have 3 values
to
> > write to the file ... I want each value on its own line. I use this code
> > (not working correctly)
> >
> > #create the file
> > open (FILE,">>datafile.inc") or die "Can't open file: $!";
>
> > close(FILE);
> >
> > #write data to file
> > open (FILE,">>datafile.inc") or die "Can't open file: $!";
> > print FILE "$value1\n";
> > print FILE "$value2\n";
> > print FILE "$value3\n";
> > close(FILE);
> >
> > After this operation is complete, I can find the file on the server.
When I
> > open it, all data is on a single line. For some reason, it's ignoring my
> > "\n"s. I also tried this:
>
>
> I'll bet your server is running some flavor of *nix, and you're running
> Windoze -- is that right? When you transfer your file back to your PC,
> be sure and use the ASCII mode of FTP (assuming, of course, that you are
> using FTP to do your file transfers). Or use a good Windoze editor that
> is capabile of handling files with *nix line endings (like VIM, for
> example).
>
> Or are you perhaps looking at your file in a web browser as an HTML
> file? Remember that all whitespace is the same in HTML -- a newline is
> treated as if it were a space character.
>
> ...
>
> > Robert
>
> --
> Bob Walton
> Email: http://bwalton.com/cgi-bin/emailbob.pl
>
------------------------------
Date: Sun, 27 Jun 2004 14:57:35 +0100
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Odd quick writing data to a file
Message-Id: <fb03r1-636.ln1@mauzo.dyndns.org>
[don't top-post]
Quoth "Robert TV" <ducott@hotmail.com>:
> I have found my problem. it has to do with the file extension oddly enough.
> To view the newly created file, I log into the server with my ftp program. I
> then double click it to execute the programs "view file" command. It opens
> in Windows Notepad. When viewing the files as an .inc extension, all data is
> on the same line. If I rename to .txt and reopen, the data is on separate
> lines ... so it appears that Notepad was the culprit.
No, your FTP client. It will be configured to transfer files with
certain extensions as 'text' and others as 'binary'. Text transfers
convert unix newlines (ascii LF) to windows (ascii CR LF), binary don't.
You can probably change the list of extensions to include any others
which you know will be text files, such as your .inc.
Ben
--
All persons, living or dead, are entirely coincidental.
ben@morrow.me.uk Kurt Vonnegut
------------------------------
Date: 27 Jun 2004 06:04:18 GMT
From: Eric Bohlman <ebohlman@omsdev.com>
Subject: Re: Printing a hash question
Message-Id: <Xns9515BA3A3E01ebohlmanomsdevcom@130.133.1.4>
John Bokma <postmaster@castleamber.com> wrote in
news:40dcad6a$0$873$58c7af7e@news.kabelfoon.nl:
>
>
> scadav wrote:
>
>> I am new to Perl and this problem is baffling me. I undestand how to
>> print out all the items in a hash and sort by the keys:
>>
>> foreach $item (sort keys(%hash)) {
>> print "$item: $hash{$item} \n";
>> }
>>
>> but how do you do the reverse of this?...print out all of the items
>> but sort on the values?
>
>
> for my $key ( sort { $hash{$a} cmp $hash{$b} } keys %hash ) {
>
> }
It's a bad idea to try to answer Frequently Asked Questions yourself rather
than referring the poster to the FAQ. IIRC, last week a well-known regular
(I forget who) let his guard down and tried to answer a FAQ himself, but in
the process he made a mistake. Another regular posted a correction, but
it's quite possible that the original poster, not to mention any number of
lurkers, stopped reading the thread as soon as they saw what looked like an
answer and missed the correction (the correction may not have made it to
their news server yet).
Someone who asks FAQs is, almost by definition, someone who doesn't yet
know enough about Perl to be able to tell whether or not he's getting a bum
steer. There's very little chance that the Perl FAQ will give them a bum
steer. There's a much greater chance that a Usenet poster will
accidentally do so.
------------------------------
Date: Sun, 27 Jun 2004 14:42:23 +0100
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: repeated calculations everyday
Message-Id: <vev2r1-636.ln1@mauzo.dyndns.org>
Quoth shalinij1@yahoo.com (Shalini Joshi):
> So here is what I have of the code uptil now.
>
> if ((localtime)[3] ==1)
> {
> print "Today is the first day of the month!\n";
> print "We are going to read all Account Position Files!\n";
Set $\="\n" rather than putting it on the end of every print.
>
> #For each client we read the Account Position File: thus all account
> position files on the server.
>
> opendir DIR, '/home/sj2122/perlstuff' or die "$!";
> my @files = grep {/[^(03)]+03\.[^\.]+\.txt$/} readdir(DIR);
> closedir(DIR);
Use lexical dirhandles.
Use scopes to close them.
Include the filename in the error message.
my @files = grep /.../, do {
my $dir = '/home/sj2122/perlstuff';
opendir my $DIR, $dir or die "can't opendir $dir: $!";
readdir $DIR;
};
> foreach $i (@files)
Why aren't you using strictures?
for my $i (@files) {
> {
> # Read every position file
> print "$i\n";
> open ACCOUNT_POSITION, "<$i" or die "Can't open $i $!";
Use lexical filehandles.
Use scopes to close them.
Use 3-arg open.
open my $ACCOUNT_POSITION, '<', $i or die "can't open $i: $!";
> local $_ = <ACCOUNT_POSITION>;
> if (/^APR/)
> {
> push @position_records,$_;
> }
Why are you manually going through one iteration of the loop below?
> while (<ACCOUNT_POSITION>)
> { #get all lines of the record
> # stop if we encounter an APR line
This doesn't stop: it records the line and carries on. If you want to
stop you will need a 'last' inside the if.
>
> if (/^APR/)
> {
> push @position_records, $_;
>
> }
I would have written this
/^APR/ and push @position_records, $_;
>
> }
> close ACCOUNT_POSITION;
There is no need for an explicit close with lexical FHs.
> }
>
> foreach $i (@position_records)
^^ my
> {
>
> %parameters_owner= (
^^ my
> dealer_number => substr($i,6,7),
> CUSIP => substr($i,22,9),
> cust_accnt_number => substr($i,38,20),
> total_shares => substr($i,59,15),
> );
>
> if ($parameters_owner{dealer_number}==7654321)
I presume there is a good reason for this value being hard-coded? If
nothing else I would put
use constant SELECTED_DEALER => 7654321;
at the top and use that instead.
> {
>
> print "Yahoo! We need to add this CUSIP number to selected records
> in Price File!\n";
>
>
> push @arrayofparams, {%parameters_owner};
If you'd properly created the %parameters_owner as a lexical the you
could simply push a reference to it
push @arrayofparams, \%parameters_owner;
and save a copy.
> push @cusip, $parameters_owner{CUSIP};
>
> push @customers, $parameters_owner{cust_accnt_number};
>
> }
>
> }
> my %hash = map {$_ => 1} @cusip;
> @cusip_new = keys %hash; # to get unique CUSIP numbers
>
> my %hash2 = map {$_ => 1} @customers;
> @customers_new = keys %hash2;
I would put each if these in a block: there is no need for the temporary
hashes to exist outside of those two statements:
my @cusip_new = do {
my %tmp = map { $_ => 1 } @cusip;
keys %tmp;
};
> foreach $i (@cusip_new)
> {
>
> my $sharetotal=0;
> for $y (0 .. $#arrayofparams)
for my $y (@arrayofparams) {
> {
> for $valuesonly (values %{ $arrayofparams[$y]} )
for my $valuesonly (values %$y) {
Are you sure this is correct? Do you not simply want to test if
$y->{CUSIP} eq $i? (I am asking 'is there an occasion where
dealer_number, cust_acct_number or total_shares will match a cusip, and
do you want to catch those matches or not?')
> {
> if ($valuesonly eq $i)
> {
> print "$valuesonly\n";
> print "$arrayofparams[$y]{total_shares}\n";
...$y->{total_shares}...
> $sharetotal += $arrayofparams[$y]{total_shares};
> }
> }
> }
> print "Total shares for $i is $sharetotal\n";
> $BASE[0]{$i}= $sharetotal; # For day 1, total for the various
> CUSIPs
Why not just build your total in $BASE[0]{$i} in the first place?
> print "$BASE[0]{$i}\n";
>
> }
> store(\@BASE, 'base_values'); # For later access.
>
> open RECORDS, "< AETNA1.txt " or die "Can't read file: $!";
>
> local $_ = <RECORDS>;
>
> while (<RECORDS>)
> { #get all lines of the record
>
> # stop if we encounter an FPR line
>
> if (/^FPR/)
> {
> push @records, $_;
> }
>
> }
>
> close RECORDS;
>
>
>
> my $date= substr(@records[0],22,8);
^ $
Why don't you have warnings turned on?
> my $cpday= &UnixDate($date,"%d");
Don't call subs with & unless you know what it does and why you need it.
> my $cpmonth=&UnixDate($date,"%m");
> my $cpyear=&UnixDate($date,"%y");
> my $cpdate=$cpmonth.$cpday.$cpyear;
>
> my $cpfilename= "AD".$cpyear.$cpmonth.$cpday."\.PRI";
my $cpfilename = UnixDate $date, 'AD%y%m%d.PRI';
> my $wanted_handle = IO::File->new($cpfilename, O_WRONLY|O_CREAT)
> or die "Couldn't open $cpfilename for writing:$!\n";
Use lexical FHs instead of IO::File; or certainly, be consistent.
It is usual to use caps for filehandles.
Don't put "\n" on the end of die messages.
> foreach $i (@records)
> {
>
> %parameters= (
>
> CUSIP_P => substr($i,6,9),
> fund_name => substr($i,59,38),
> processing_date => $cpdate,
processing_data => UnixData $data, '%m%d%y';
Except don't use m-d-y date formats, they're just too brain-damaged for
words...
> NAV_P => substr($i,30,9),
> Fund_Type_P => "MU",
> Public_Offering_Price => "000".substr($i,39,9),
> );
>
>
> foreach $selectedcusip (@cusip_new)
> {
> if ($selectedcusip eq $parameters{CUSIP_P})
> {
> push @arraypriceparams, {%parameters};
>
> }
>
> }
> }
>
>
> for $x (0 .. $#arraypriceparams)
>
> {
> print $wanted_handle
> "$arraypriceparams[$x]{CUSIP_P},$arraypriceparams[$x]{Fund_Type_P},$arraypriceparams[$x]{processing_date},$arraypriceparams[$x]{Public_Offering_Price}\n";
> }
>
>
> }
>
> #If not the first day of the month, read DIRECT FINANCIAL ACTIVITY
> FILE
>
> else
> {
> my $mday = (localtime)[3];
> print "Today we are going to read the Direct Financial Acitivity
> File and see the status of our CUSIPs!\n";
>
> # Retrieving all base values
>
> my $base_ref = retrieve('base_values');
>
> #my @BASE = @{$base_ref};
> #foreach $i (@{$base_ref})
> #{
> # print "$i{AET001A70}";
> #}
> print "$$base_ref[0]{AET001A20}\n";
>
> The thing that has me stumped is how do access the BASE array that I
> stored using the storable module. When i try and print out the
> particular element, it works but doesnt work ..gives me a HASH{xxxx}
> error...
Please explain...your $base_ref is here a ref to an array of hashes, as
you seem to have figured out; I would have written the deref above
$base_ref->[0]{AET001A20}
. If you want to loop, you will need @$base_ref:
for my $i (@$base_ref) {
print $i->{AET001A70};
}
> also as I mention right at the end I store it as BASE[0][$i]
> where $i is an element of an array of unique 9 digit numbers. (not
> necessarily sorted etc)...Is there any way I can get it to print based
> on the length of the hard-linked array..as opposed to the index or
> something???
Please explain more clearly what you want... what do you mean by 'print
based on'? Do you mean 'print a list sorted by'? And there is no such
thing as a 'hard-linked array' in Perl: the only link between
$BASE[0]{$i} and @cusp_ip is the value they hold in common.
Ben
--
"If a book is worth reading when you are six, * ben@morrow.me.uk
it is worth reading when you are sixty." - C.S.Lewis
------------------------------
Date: 27 Jun 2004 06:03:16 -0700
From: jl_post@hotmail.com (J. Romano)
Subject: Re: Splitting a file
Message-Id: <b893f5d4.0406270503.7d6ecffe@posting.google.com>
pincopallo_it@yahoo.it (Gianni) wrote in message news:<3c03ef0c.0406250439.535f6897@posting.google.com>...
> I have a file done like this
>
> |
> |
> cat
> dog
> monkey
> troll
> |
> |
> silver
> gold
> |
> |
> rome
> london
> praha
> |
> | etc.............
>
> how can I create a new file after the || ??
Dear Gianni,
That's easy enough to do in Perl by setting the record separator
(the $/ variable) to "|\n|\n". That way, when you read in your file
the usual way, you will get records like:
cat
dog
monkey
troll
|
|
The || will still appear at the end of each record. To get rid of
those, all you have to do is call chomp on each record.
What you didn't specify is what to name each file (you didn't make
that clear). I wrote a short script for you, but since I didn't know
what to name the files, I asked the user for a file name.
One snag I ran into: Since I set the record separator to "|\n|\n"
to read in the data, I had to set it BACK to "\n" to read in the file
name from STDIN when asking the user for a file name.
My script follows. Save the script and the data after it to a file
named something like "gianni.pl" and then type "perl gianni.pl". That
should do exactly what you want.
Spero che questo ti aiuti.
-- Jean-Luc
#!/usr/bin/perl -w
use strict;
$| = 1; # autoflush for STDOUT
$/ = "|\n|\n"; # set the record separator to the two pipes
while (<DATA>)
{
# The record (including the ||) is now in $_
chomp($_); # remove the || from the record
# Skip this record if it is empty:
next if length($_) == 0;
# Ask for a file name:
print " The following lines:\n";
print $_;
print " have been found.\n";
print " Name the file you want to save them into: ";
# Get the file name from the user:
my $fileName;
{
# We want to get a new file name from STDIN,
# so we have to (temporarily) set the record
# separator back to a newline. For this, we
# use the "local" keyword:
local $/ = "\n";
$fileName = <STDIN>;
chomp($fileName); # remove the newline
}
# Write to file:
open(FILE, "> $fileName")
or die "ERROR: Cannot write to file \"$fileName\": $!\n";
print FILE $_;
close(FILE);
print "File \"$fileName\" successfully saved.\n\n";
}
__DATA__
|
|
cat
dog
monkey
troll
|
|
silver
gold
|
|
rome
london
praha
|
|
------------------------------
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 6736
***************************************