[23249] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 5470 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Sep 9 14:07:23 2003

Date: Tue, 9 Sep 2003 11:05:11 -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           Tue, 9 Sep 2003     Volume: 10 Number: 5470

Today's topics:
        "between" function equivalent in Perl? <scorpiorising@ftml.net>
    Re: "between" function equivalent in Perl? <mpapec@yahoo.com>
    Re: "between" function equivalent in Perl? <no@email.com>
    Re: "between" function equivalent in Perl? (Anno Siegel)
    Re: "between" function equivalent in Perl? <print split /!/"d!a!v!i!d!o!@!p!a!c!i!f!i!e!r!.!c!o!m!\n">
    Re: Can Perl do this? (siva chelliah)
        Counting files <shawn@magma.ca>
    Re: Creating a DSN-less connection to a MySQL database <jwillmore@cyberia.com>
    Re: dynamic access to multidimensional array <abigail@abigail.nl>
    Re: dynamic access to multidimensional array (Anno Siegel)
    Re: dynamic access to multidimensional array <nobull@mail.com>
    Re: dynamic access to multidimensional array <nobull@mail.com>
    Re: Flocking Advise (David Efflandt)
    Re: Flocking Advise ctcgag@hotmail.com
    Re: Flocking Advise news@roaima.freeserve.co.uk
    Re: Flocking Advise <flavell@mail.cern.ch>
    Re: illegal seek news@roaima.freeserve.co.uk
    Re: illegal seek (Anno Siegel)
    Re: illegal seek <minceme@start.no>
    Re: multiple arrays from one text file with one column <cs@edu.edu>
    Re: multiple arrays from one text file with one column (Anno Siegel)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Tue, 9 Sep 2003 10:08:04 -0700
From: "Alexandra" <scorpiorising@ftml.net>
Subject: "between" function equivalent in Perl?
Message-Id: <bjl1dk$e7n$1@lumberjack.rand.org>

Hello All-

I'm attempting to extract a substring of characters from an alphanumeric
text string. I've read a lot of Perl documentation on the 'index' and
'substring' functions; however, I cannot find a regular expression (or an
example of one) that is the equivalent of a "between" function in Perl. Perl
is very good at string manipulation so I assume there must be a way to do
this. Here's what I'm trying to do:

$mystring = 'aaa @ bbbb @ c @ dd @ eeeeee @ FFFFF=xxxx @ ggg @ h'

The goal is to extract the 'xxxx' substring between the '=' sign and the
next whitespace character. (There is no fixed length for the 'xxxx'
substring.)

Rather than use a series of clunky index and substring calls, does anyone
have a better suggestion? If anyone can recommend a good Perl language
reference website (or book) that has some excellent examples of regular
expressions, that would be helpful too.

Thanks in advance,

Alexandra




------------------------------

Date: Tue, 09 Sep 2003 19:53:09 +0200
From: Matija Papec <mpapec@yahoo.com>
Subject: Re: "between" function equivalent in Perl?
Message-Id: <3j4slvc57g4pm3in97jf7s89po85cjlt1c@4ax.com>

X-Ftn-To: Alexandra 

"Alexandra" <scorpiorising@ftml.net> wrote:
>example of one) that is the equivalent of a "between" function in Perl. Perl
>is very good at string manipulation so I assume there must be a way to do
>this. Here's what I'm trying to do:
>
>$mystring = 'aaa @ bbbb @ c @ dd @ eeeeee @ FFFFF=xxxx @ ggg @ h'
>
>The goal is to extract the 'xxxx' substring between the '=' sign and the
>next whitespace character. (There is no fixed length for the 'xxxx'
>substring.)

my($match) = $mystring =~ /=(\S+)/;

>Rather than use a series of clunky index and substring calls, does anyone
>have a better suggestion? If anyone can recommend a good Perl language
>reference website (or book) that has some excellent examples of regular
>expressions, that would be helpful too.

I've heard that "Mastering regular expression" is very good.



-- 
Matija


------------------------------

Date: Tue, 9 Sep 2003 18:55:03 +0100
From: "Brian Wakem" <no@email.com>
Subject: Re: "between" function equivalent in Perl?
Message-Id: <bjl45o$k7ojk$1@ID-112158.news.uni-berlin.de>


"Alexandra" <scorpiorising@ftml.net> wrote in message
news:bjl1dk$e7n$1@lumberjack.rand.org...
> Hello All-
>
> I'm attempting to extract a substring of characters from an alphanumeric
> text string. I've read a lot of Perl documentation on the 'index' and
> 'substring' functions; however, I cannot find a regular expression (or an
> example of one) that is the equivalent of a "between" function in Perl.
Perl
> is very good at string manipulation so I assume there must be a way to do
> this. Here's what I'm trying to do:
>
> $mystring = 'aaa @ bbbb @ c @ dd @ eeeeee @ FFFFF=xxxx @ ggg @ h'
>
> The goal is to extract the 'xxxx' substring between the '=' sign and the
> next whitespace character. (There is no fixed length for the 'xxxx'
> substring.)
>
> Rather than use a series of clunky index and substring calls, does anyone
> have a better suggestion? If anyone can recommend a good Perl language
> reference website (or book) that has some excellent examples of regular
> expressions, that would be helpful too.


print $mystring =~ m/=([^\s]+)/;

-- 
Brian Wakem




------------------------------

Date: 9 Sep 2003 17:57:41 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: "between" function equivalent in Perl?
Message-Id: <bjl4al$lbs$1@mamenchi.zrz.TU-Berlin.DE>

Alexandra <scorpiorising@ftml.net> wrote in comp.lang.perl.misc:
> Hello All-
> 
> I'm attempting to extract a substring of characters from an alphanumeric
> text string. I've read a lot of Perl documentation on the 'index' and
> 'substring' functions; however, I cannot find a regular expression (or an
> example of one) that is the equivalent of a "between" function in Perl. Perl
> is very good at string manipulation so I assume there must be a way to do
> this. Here's what I'm trying to do:
> 
> $mystring = 'aaa @ bbbb @ c @ dd @ eeeeee @ FFFFF=xxxx @ ggg @ h'
> 
> The goal is to extract the 'xxxx' substring between the '=' sign and the
> next whitespace character. (There is no fixed length for the 'xxxx'
> substring.)

The notion of "between" can very well be expressed in regular expressions.
If $from and $to are regular expressions, the expression /$from(.*)$to/
catches everything between the first match of $from and the last
match of $to.  If you want to delimit from the first match of $from
to the first match of $to after that point, use a non-greedy pattern in the
middle: /from(.*?)$to/.  In your case it doesn't matter:

my $from = qr/=/; # a "="
my $to = qr/\s/;  # any white space
my ( $between) = $mystring =~ /$from(.*?)$to/;
print "$between\n";

That prints "xxxx".

Anno


------------------------------

Date: Tue, 9 Sep 2003 11:04:13 -0700
From: "David Oswald" <print split /!/"d!a!v!i!d!o!@!p!a!c!i!f!i!e!r!.!c!o!m!\n">
Subject: Re: "between" function equivalent in Perl?
Message-Id: <vls5gcds9rpb7@corp.supernews.com>


"Alexandra" <scorpiorising@ftml.net> wrote in message
news:bjl1dk$e7n$1@lumberjack.rand.org...
> Hello All-
>
> I'm attempting to extract a substring of characters from an alphanumeric
> text string. I've read a lot of Perl documentation on the 'index' and
> 'substring' functions; however, I cannot find a regular expression (or an
> example of one) that is the equivalent of a "between" function in Perl.
Perl
> is very good at string manipulation so I assume there must be a way to do
> this. Here's what I'm trying to do:

You read a "lot" of Perl documentation, and regular expression discussion,
and didn't find anything therein that inspired a solution?

> $mystring = 'aaa @ bbbb @ c @ dd @ eeeeee @ FFFFF=xxxx @ ggg @ h'
>
> The goal is to extract the 'xxxx' substring between the '=' sign and the
> next whitespace character. (There is no fixed length for the 'xxxx'
> substring.)

Assuming there is only one occurrence per string, and that there are no
newlines in the string, this works.
my $matched = $mystring =~ m/=(.*?)\s/;

If there is more than one occurrence per string, and equals may also be
embedded in the portion of the string you're attempting to extract, it
becomes more complicated.  Assuming that the space character is unique in
that it is always a delimiter, then you probably should make your life a
little easier by first splitting on space, just so that you don't have to
write a regexp that handles embedded equals differently from
string-initiated equals signs, and stuff like that.



> Rather than use a series of clunky index and substring calls, does anyone
> have a better suggestion? If anyone can recommend a good Perl language
> reference website (or book) that has some excellent examples of regular
> expressions, that would be helpful too.

Have you tried the perldocs, specifically 'perldoc perlbook' for book
suggestions?  The bible is the Camel book (Programming Perl), and the sunday
school lesson manual is Learning Perl (the Llama book).





------------------------------

Date: 9 Sep 2003 08:59:00 -0700
From: podian@yahoo.com (siva chelliah)
Subject: Re: Can Perl do this?
Message-Id: <5d146344.0309090759.a6d790@posting.google.com>

I am amazed when people ask:
   a) I have no clue about perl
   b) I want to do X
   c) Can perl do this?

It basically says that they want us to do their job. I am unemployed,
can I get that job (since I know how to do that!)?

Is there any recommended things to do to get a feel of a new language?
Such as:
     a) write 'hello world'
     b) Learn about string manipulations
     c) File IO
     d) and so on.


Siva


f_baggins80@hotmail.com (Helgi Briem) wrote in message news:<3f5c548b.238949781@News.CIS.DFN.DE>...
> On Mon, 08 Sep 2003 01:23:09 GMT, CountryLover
> <crazygonuts@pcgeek.invalid> wrote:
> 
> >A project that I am working on requires the following steps:
> >
> >1. Parse a directory containing text files, potentially thousands 
> 
> perldoc perlrun
> perldoc warnings
> perldoc strict
> perldoc -f opendir
> perldoc -f grep
> perldoc -f readdir
> perldoc -f die
> perldoc perlvar  ($!)
> perldoc File::Find  (if there are subdirectories)
> 
> >2. Open each text file and read in the first 25 lines or so
> 
> perldoc -f open
> perldoc perlvar  ( $. ) 
> perldoc perlsyn (while)
> 
> >3. Write these lines to a temporary file
> 
> perldoc -f open
> perldoc -f print
> perldoc -f close
> 
> >4. Delete each original file & replace with the temp file, using same filename
> 
> perldoc -f unlink
> 
> >5. Parse the truncated files and find a specific keyword
> 
> perldoc perlre  (or perldoc perlrequick)
> 
> >6. Create directories based on the value of the keywords found
> 
> perldoc -f mkdir
> 
> >7. Move the truncated files to their respective directories.
> 
> perldoc -f rename
> 
> >8. Optionally, create a log file of all operations
> 
> perldoc -f open
> perldoc -f print
> 
> >Is this something that Perl could be persuaded to do?
> 
> Of course.  What have you tried so far?


------------------------------

Date: Tue, 09 Sep 2003 13:45:19 -0400
From: Shawn Corey <shawn@magma.ca>
Subject: Counting files
Message-Id: <b9SdncIafYkfjMOiU-KYuQ@magma.ca>

Hi,

I have a list:

file1
file2
dir1/file3
dir1/file4
dir1/subdir1/file5
dir2/file6
 ...

I want to count them like:

$File{.}{file1} = count;
$File{.}{file2} = count;
$File{dir1}{file3} = count;
$File{dir1}{file4} = count;
$File{dir1}{subdir1}{file5} = count;
$file{dir2}{file6} = count;
 ...

Is the a nifty way of doing this in Perl-speak?



------------------------------

Date: Tue, 09 Sep 2003 16:38:25 GMT
From: James Willmore <jwillmore@cyberia.com>
Subject: Re: Creating a DSN-less connection to a MySQL database
Message-Id: <20030909123830.2ce6ab2f.jwillmore@cyberia.com>

On Tue, 9 Sep 2003 13:37:09 +0100
"Al Reynolds" <al@bat400.com> wrote:
> I hope someone will be able to help me with this.
> 
> I am trying to set up a connection to my MySQL
> database using perl.  I already have the database
> set up and have used it with PHP without any problems.
> 
> When I try and execute the following code, I get an error:
> (obviously I have substituted the names/passwords)
> 
> #!/usr/bin/perl
> use DBI;
> my $dbh =
> DBI->connect('DBI:mysql:databasename:localhost','username','passwor
> d');$dbh->disconnect or warn "Disconnection error: $DBI::errstr\n";
> exit;

Try to first, read the documentation for DBD::mysql and second, try to
connect using ...

DBI->connect('DBI:mysql:database=dbname;host=localhost',
	'username',
	'password')
	or die "Connection error: ".$DBI::errstr."\n";

If you had read the documentation, you would have discovered that your
connection statement is wrong.

HTH

-- 
Jim

Copyright notice: all code written by the author in this post is
 released under the GPL. http://www.gnu.org/licenses/gpl.txt 
for more information.

a fortune quote ...
Never offend people with style when you can offend them with
substance.   -- Sam Brown, "The Washington Post", January 26,
1977 


------------------------------

Date: 09 Sep 2003 15:24:27 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: dynamic access to multidimensional array
Message-Id: <slrnblrs5b.djm.abigail@alexandra.abigail.nl>

Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
<URL:news:u9ad9eywat.fsf@wcl-l.bham.ac.uk>:
`'  kompakt17@gmx.net (Stefan Schnitter) writes:
`'  
`' > Is it somehow possible to index an array by another array?
`' > Example:
`' > 
`' >            @AoA = (
`' >                   [ "fred", "barney" ],
`' >                   [ "george", "jane", "elroy" ],
`' >                   [ "homer", "marge", "bart" ],
`' >            );
`' > 
`' > and I have another array 
`' > 
`' >            @ind = ( 0, 1 );
`' > 
`' > How can I use @ind to index @AoA to get $AoA[0][1] ?
`'  
`'  #!/usr/bin/perl
`'  use strict;
`'  use warnings;
`'  
`'  sub index_AoA : lvalue {
`'      my $v = \shift;
`'      $v = \$$v->[$_] for @{shift()};
`'      $$v;
`'  }
`'  
`'  my @AoA = (
`'  	   [ "fred", "barney" ],
`'  	   [ "george", "jane", "elroy" ],
`'  	   [ "homer", "marge", "bart" ],
`'             );
`'  
`'  my @ind = ( 0, 1 );
`'  
`'  print index_AoA(\@AoA,\@ind),"\n";
`'  
`'  index_AoA(\@AoA,[1,1]) = 'june';
`'  
`'  print $AoA[1][1],"\n";



Eck. Why so difficult? 'eval' makes it very easy:

    #!/usr/bin/perl

    use strict;
    use warnings;

    my @AoA = ([qw /fred barney/],
               [qw /george jane elroy/],
               [qw /homer marge bart/]);

    my @ind = (0, 1);

    my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
    die $@ if $@;

    print $elem, "\n";
    __END__
    barney



Abigail
-- 
perl -wle 'eval {die ["Just another Perl Hacker"]}; print ${${@}}[$#{@{${@}}}]'


------------------------------

Date: 9 Sep 2003 16:09:47 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: dynamic access to multidimensional array
Message-Id: <bjku0b$hfm$1@mamenchi.zrz.TU-Berlin.DE>

Abigail  <abigail@abigail.nl> wrote in comp.lang.perl.misc:
> Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in
> <URL:news:u9ad9eywat.fsf@wcl-l.bham.ac.uk>:
> `'  kompakt17@gmx.net (Stefan Schnitter) writes:
> `'  
> `' > Is it somehow possible to index an array by another array?
> `' > Example:
> `' > 
> `' >            @AoA = (
> `' >                   [ "fred", "barney" ],
> `' >                   [ "george", "jane", "elroy" ],
> `' >                   [ "homer", "marge", "bart" ],
> `' >            );
> `' > 
> `' > and I have another array 
> `' > 
> `' >            @ind = ( 0, 1 );
> `' > 
> `' > How can I use @ind to index @AoA to get $AoA[0][1] ?

[snip of recursive solution]

> Eck. Why so difficult? 'eval' makes it very easy:
> 
>     #!/usr/bin/perl
> 
>     use strict;
>     use warnings;
> 
>     my @AoA = ([qw /fred barney/],
>                [qw /george jane elroy/],
>                [qw /homer marge bart/]);
> 
>     my @ind = (0, 1);
> 
>     my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
>     die $@ if $@;
> 
>     print $elem, "\n";
>     __END__
>     barney

The usual security concerns apply if @AoA comes from outside the program.
I wonder what's more efficient, but not enough to benchmark.

That aside, the solution is cute, but it looks like cheating.  From one
point of view, it isn't a solution at all.  It doesn't solve the problem
of multi-level indexing but uses the solution built into the Perl interpreter.
Thus, it gives no insight into the problem.

Of course, if the task isn't to gain insight but to get it done, it's
code re-use at its finest.

Anno


------------------------------

Date: 09 Sep 2003 17:34:53 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: dynamic access to multidimensional array
Message-Id: <u94qzlzzrm.fsf@wcl-l.bham.ac.uk>

Abigail <abigail@abigail.nl> writes:

> Brian McCauley (nobull@mail.com) wrote on MMMDCLXI September MCMXCIII in

> `'  sub index_AoA : lvalue {
> `'      my $v = \shift;
> `'      $v = \$$v->[$_] for @{shift()};
> `'      $$v;
> `'  }

> Eck. Why so difficult? 'eval' makes it very easy:
> 
>     my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
>     die $@ if $@;

Thankyou!  I'm planning to do a talk at YAPC::Europe::2004 about some
of the issues surrounding the good the bad and the ugly uses of
eval-string.  

I needed some good non-trivial examples where a simple eval solution
exists to a problem and were it looks amazingly elegant at one level
but is actually aborrently ugly to an experienced programmer.

BTW: You should have put some smileys in there.  Some people may have
actually thought you were serious.  I trust you _were_ joking.

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


------------------------------

Date: 09 Sep 2003 17:36:58 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: dynamic access to multidimensional array
Message-Id: <u9znhdyl3p.fsf@wcl-l.bham.ac.uk>

anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) writes:

> Abigail  <abigail@abigail.nl> wrote in comp.lang.perl.misc:
>
> >     my $elem = do {local $" = "]["; eval "\$AoA [@ind]"};
> 
> The usual security concerns apply if @AoA comes from outside the program.

Unless I'm missing something, you mean @ind, not @AoA.

-- 
     \\   ( )
  .  _\\__[oo
 .__/  \\ /\@
 .  l___\\
  # ll  l\\
 ###LL  LL\\


------------------------------

Date: Tue, 9 Sep 2003 15:38:09 +0000 (UTC)
From: efflandt@xnet.com (David Efflandt)
Subject: Re: Flocking Advise
Message-Id: <slrnblrsv1.adc.efflandt@typhoon.xnet.com>

On Tue, 9 Sep 2003, news@roaima.freeserve.co.uk 
<news@roaima.freeserve.co.uk> wrote:
> David Efflandt <efflandt@xnet.com> wrote:
>> My approach is to open it read/write ( +< ), flock it, seek the beginning
>> (just in case something else opened it before flock), modify and save
>> data, and then close it.
> 
> There's a very similar issue going on in a parallel thread at the moment.
> 
> What I really don't see is why there's a requirement to seek back to the
> beginning of a file after it's been flocked. If you've not read anything
> then the file pointer's at the start of the file anyway. (flock applies a
> file lock rather than a partial region lock.) I appreciate you need a seek
> when swapping between reading and writing, but that's not the issue here.
> 
> Can anyone give a concrete explanation as to why the seek is required
> immediately after the flock?

perldoc -f flock

Basically something else could open the file (possibly for reading)  
between the time you open it, and flock it, so the file pointer might not
be at the beginning of the file when you go to read it.  It may not always
be necessary, but it is playing it safe, just in case.

-- 
David Efflandt - All spam ignored  http://www.de-srv.com/


------------------------------

Date: 09 Sep 2003 15:51:38 GMT
From: ctcgag@hotmail.com
Subject: Re: Flocking Advise
Message-Id: <20030909115138.783$0Z@newsreader.com>

"\"Dandy\" Randy" <ducott@hotmail.com> wrote:
> Hey ... could use some advise on the best file locking method ... at
> present I use the following:
>
> #!/usr/bin/perl
>
> use strict;
> use 5.004;
> use Fcntl qw(:DEFAULT :flock);
>
> open (FH, "<data.txt") or die "Can't open file: $!";
> flock (FH, LOCK_EX) or die "Can't lock file: $!";
> $data=<FH>;
> chomp ($data);
> ($total,$opened,$followed)=split(/\|/,$data);
> close(FH);

Bang, you're dead!  There was no point taking out an exclusive lock,
since you just lost it before the write occured.


> $opened = $opened + 1;
>
> sysopen(FH, "data.txt", O_WRONLY | O_CREAT) or die "can't open filename:
> $!";
> flock (FH, LOCK_EX) or die "can't lock filename: $!";
> truncate (FH, 0) or die "can't truncate filename: $!";
> print FH "$total|$opened|$followed\n";
> close FH;
>
> print "Content-type: text/html \n\n";
> print "Done\n";
> exit;
>
> It seems to work ok, but am not sure if it is a good approach or not.

It is not.  Both operations need to take place under the *same lock*,
not under two different locks.  If it seems to work, you are probably
not testing under sufficiently contentious conditions.

> One
> of my main questions is ... what about sememorph locks ... been reading
> in different places that you start you file open code by opening a dummy
> sememorph file ... kinda like this:

You do not need to do this if flock works properly on your system.

One things you could do is open the file for read and write,
obtain the EX lock, read, truncate, write, close.

Another way is to use the file as it's own semaphore:
open FH for reading, obtain EX lock, read.  *Do not close FH*
open FH2 for writing to the same file.  (There is no need to lock
it as FH holds the lock on FH2's behalf).  Write to FH2, close
FH2, close FH.

This last is the way I usually do it, as I've never bothered to
learn how to use truncate and +<.


Xho

-- 
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service              New Rate! $9.95/Month 50GB


------------------------------

Date: Tue, 9 Sep 2003 17:27:16 +0100
From: news@roaima.freeserve.co.uk
Subject: Re: Flocking Advise
Message-Id: <4kb131-ant.ln1@moldev.cmagroup.co.uk>

<news@roaima.freeserve.co.uk> asked:
> Can anyone give a concrete explanation as to why the seek is required
> immediately after the flock?

David Efflandt <efflandt@xnet.com> wrote:
> perldoc -f flock

The seek to EOF is correct when you're appending to a file. In the
general case (and particularly when reading) it's not required.

> Basically something else could open the file (possibly for reading)  
> between the time you open it, and flock it, so the file pointer might not
> be at the beginning of the file when you go to read it.

The file pointer is on a per-filehandle basis, not on a per-file
basis. We'd get mighty upset if I changed my file pointer and yours
updated too.

The notable exception is when *writing*, where we've specified that all
writing is to occur at the current EOF (i.e. append), in which case it's
correct behaviour).

Chris
-- 
@s=split(//,"Je,\nhn ersloak rcet thuarP");$k=$l=@s;for(;$k;$k--){$i=($i+1)%$l
until$s[$i];$c=$s[$i];print$c;undef$s[$i];$i=($i+(ord$c))%$l}


------------------------------

Date: Tue, 9 Sep 2003 19:04:59 +0200
From: "Alan J. Flavell" <flavell@mail.cern.ch>
Subject: Re: Flocking Advise
Message-Id: <Pine.LNX.4.53.0309091837350.5973@lxplus015.cern.ch>

On Tue, Sep 9, ctcgag@hotmail.com inscribed on the eternal scroll:

> One things you could do is open the file for read and write,
> obtain the EX lock, read, truncate, write, close.

This is an FAQ, isn't it?  It always makes me nervous to see
independent proposals offered to the readership when there's an
existing FAQ that addresses their requirement. If the FAQ is wrong or
incomplete or otherwise unsatisfactory, it seems to me that discussion
should focus on a proposal for a revised FAQ, rather than offering the
readership some kind of parallel-universe advice.  No offence meant.

> Another way is to use the file as it's own semaphore:
> open FH for reading, obtain EX lock, read.  *Do not close FH*
> open FH2 for writing to the same file.  (There is no need to lock
> it as FH holds the lock on FH2's behalf).  Write to FH2, close
> FH2, close FH.

But now we're going in circles, because in a very recent posting on
this topic a contributor pointed out - and the FAQ says so too - that
on some platforms you can't get an exclusive lock without opening for
write.

See also the file-locking part of perlopentut (again, if there's
something wrong, the discussion should IMHO be contributing to fix it,
not just talking across it...)

> This last is the way I usually do it, as I've never bothered to
> learn how to use truncate and +<.

Well, I can only say that according to the available documentation,
your method appears to be less portable.  OK, OK, as the FAQ says:

| Slavish adherence to portability concerns shouldn't get in the way
| of your getting your job done.

but where there's a choice, I'd try to incline to the portable one.

best regards

http://www.perldoc.com/perl5.8.0/pod/perlfaq5.html#How-can-I-lock-a-file-
http://www.perldoc.com/perl5.8.0/pod/perlopentut.html#File-Locking


------------------------------

Date: Tue, 9 Sep 2003 17:22:50 +0100
From: news@roaima.freeserve.co.uk
Subject: Re: illegal seek
Message-Id: <qbb131-ant.ln1@moldev.cmagroup.co.uk>

Alan J. Flavell <flavell@mail.cern.ch> wrote:
> Yes, I agree: but I've heard people saying that it would take them a
> long time to read their file, but adding a new record at the end would
> be fast, so can't they take a shared lock to read the file, and then
> somehow upgrade it to an exclusive lock to add the new record?

Hmm (puts thinking hat on). What about this (with dies omitted):

	open (F, "<+ somefile");
	flock F, LOCK_SH;
	# Do lots of reads

	flock F, LOCK_EX;
	seek F, END_OF_FILE;	# Can't remember symbolic offhand
	# Do lots of writes at EOF

	close F;

Chris
-- 
@s=split(//,"Je,\nhn ersloak rcet thuarP");$k=$l=@s;for(;$k;$k--){$i=($i+1)%$l
until$s[$i];$c=$s[$i];print$c;undef$s[$i];$i=($i+(ord$c))%$l}


------------------------------

Date: 9 Sep 2003 16:49:43 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: illegal seek
Message-Id: <bjl0b7$hfm$3@mamenchi.zrz.TU-Berlin.DE>

Alan J. Flavell <flavell@mail.cern.ch> wrote in comp.lang.perl.misc:
> On Tue, Sep 9, news@roaima.freeserve.co.uk inscribed on the eternal scroll:
> 
> > Alan J. Flavell <flavell@mail.cern.ch> wrote:
> > >> Get shared locks for reading and exclusive locks for writing.
> >
> > > Indeed.  However, AIUI anyone who's reading a file in order to
> > > subsequently update it will need an exclusive lock from the start.
> >
> > Yes - but in this case you'd open the file for updating (with "<+ $file"),
> > so it's effectively an exclusive write lock that you'd need here anyway.
> 
> Yes, I agree: but I've heard people saying that it would take them a
> long time to read their file, but adding a new record at the end would
> be fast, so can't they take a shared lock to read the file, and then
> somehow upgrade it to an exclusive lock to add the new record?
> Sounds a plausible idea, but I don't think it can be done in those
> terms.

That's a good description of the scenario where a lock upgrade looks
tempting.  But, as you say, it can't be done.  To get a write lock, you'd
have to give up the read lock, which means someone else can change the
file before you do.  End of story, until an OS gives us LOCK_UPGD.

Anno


------------------------------

Date: Tue, 9 Sep 2003 17:41:46 +0000 (UTC)
From: Vlad Tepes <minceme@start.no>
Subject: Re: illegal seek
Message-Id: <bjl3cq$9aa$1@troll.powertech.no>

Anno Siegel <anno4000@lublin.zrz.tu-berlin.de> wrote:

 ...

> But, as you say, it can't be done.  To get a write lock, you'd
> have to give up the read lock, which means someone else can change the
> file before you do.  End of story, until an OS gives us LOCK_UPGD.

Are you sure about this? I've tried Chris's idea. It seems to be
possible to upgrade the lock from LOCK_SH to LOCK_EX without unlocking
first, but I could be missing something.

Here are the two scripts I tried, followed by output from a small
command line session:

lockupgrade.pl:

    #!/usr/bin/perl -w

    use strict; 
    use Fcntl qw( :flock :seek );
    $|++;

    open F, "+<", "lock.txt"    or die "$0 open : $!";
    print "\n$0: waiting for shared lock...";
    flock F, LOCK_SH            or die "$0 flocksh : $!";
    print "\n$0: got shared lock\n";
    sleep 10;

    print "$0: waiting for exclusive lock...\n";
    flock F, LOCK_EX            or die "$0 flockex: $!";
    print "$0: got exclusive lock!\n";
    seek  F, SEEK_END, 2        or die "$0 seekend: $!";
    print F "\nwritten by $0 at @{[ scalar localtime ]}\n";
    flock F, LOCK_UN            or die "$0 cannot unlock: $!";
    close F                     or die "$0 closeex: $!";

    __END__


locksh.pl:

    #!/usr/bin/perl

    use warnings;
    use strict;
    use Fcntl qw( :flock :seek );

    open  F, "lock.txt"      or die "open : $!";
    print "$0: waiting for shared lock..\n";
    flock F, LOCK_SH        or die "$0 flocksh: $!";
    print "$0: got shared lock!....\n";
    sleep 10;
    flock F, LOCK_UN        or die "$0 unlock: $!";
    print "$0: released readlock!....\n";
    close F;

    __END__

Here's what I did, together with output:

    $ perl lockupg.pl &; sleep 2; perl locksh.pl ; sleep 3

    [1] 5265
    lockupg.pl: waiting for shared lock...
    lockupg.pl: got shared lock
    locksh.pl: waiting for shared lock..
    locksh.pl: got shared lock!....
    lockupg.pl: waiting for exclusive lock...
    locksh.pl: released readlock!....
    lockupg.pl: got exclusive lock!
    [1]  + 5265 done       perl lockupg.pl
    $ cat lock.txt
    la
    lala
    lalala
    lalalala

    written by lockupg.pl at Tue Sep  9 19:33:44 2003
    $

-- 
Vlad


------------------------------

Date: Tue, 09 Sep 2003 09:30:43 -0700
From: Chief Squawtendrawpet <cs@edu.edu>
Subject: Re: multiple arrays from one text file with one column
Message-Id: <3F5E0033.FDBC7507@edu.edu>

Anno Siegel wrote:
>     my ( @names, @address, @phone, @age);
>     push @{ ( \ ( @names, @address, @phone, @age) )[ $. % 4]}, $_ while <DATA>;

Don't you need to use this instead: [($. - 1) % 4]

Otherwise, the items end up in the wrong arrays.

Can anyone help me understand why/how this code works?
   \ ( @names, @address, @phone, @age)

Does it produce the same thing as this?
   (\@names, \@address, \@phone, \@age)

Chief S.


------------------------------

Date: 9 Sep 2003 17:25:26 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: multiple arrays from one text file with one column
Message-Id: <bjl2e6$jlo$1@mamenchi.zrz.TU-Berlin.DE>

Chief Squawtendrawpet  <cs@edu.edu> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
> >     my ( @names, @address, @phone, @age);
> >     push @{ ( \ ( @names, @address, @phone, @age) )[ $. % 4]}, $_
> while <DATA>;
> 
> Don't you need to use this instead: [($. - 1) % 4]
> 
> Otherwise, the items end up in the wrong arrays.

Right.  Or make it more obscure:

    push @{ ( \ ( @age, @names, @address, @phone) )[ $. % 4]}, $_
        while <DATA>;

> Can anyone help me understand why/how this code works?
>    \ ( @names, @address, @phone, @age)
> 
> Does it produce the same thing as this?
>    (\@names, \@address, \@phone, \@age)

Yes.  It's an obscure feature of the backslash operator, but it has its
uses.  See perldoc perlref.

Anno


------------------------------

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 5470
***************************************


home help back first fref pref prev next nref lref last post