[21796] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 4000 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Oct 20 09:05:42 2002

Date: Sun, 20 Oct 2002 06:05:09 -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, 20 Oct 2002     Volume: 10 Number: 4000

Today's topics:
        Accessing data from constructor (kit)
    Re: Accessing data from constructor <jkeen@concentric.net>
    Re: Accessing data from constructor <jkeen@concentric.net>
    Re: Accessing data from constructor (Tad McClellan)
    Re: Controlling recursion depth with File::Find <bik.mido@tiscalinet.it>
    Re: Controlling recursion depth with File::Find <goldbb2@earthlink.net>
    Re: DBI module INSERT command problem <pilsl_use@goldfisch.at>
        File::CounterFile and DEFAULT_DIR? <gerry1@dircon.co.uk>
        gave a2p, s2p a one-liner, want one-liner back <jidanni@dman.ddts.net>
    Re: gave a2p, s2p a one-liner, want one-liner back (Tad McClellan)
    Re: How to parse command line keywords? <chris@home.com>
    Re: IO::Handle::setvbuf not implemented on this archite <goldbb2@earthlink.net>
    Re: Making a server both standalone and tcpd <goldbb2@earthlink.net>
    Re: Need advice on a project (wrt to tie'ing to a file  <bik.mido@tiscalinet.it>
    Re: processing lines in pairs <goldbb2@earthlink.net>
    Re: References to substrings (Peter Erl)
    Re: References to substrings <Tassilo.Parseval@post.rwth-aachen.de>
    Re: References to substrings <goldbb2@earthlink.net>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: 20 Oct 2002 00:17:45 -0700
From: manutd_kit@yahoo.com (kit)
Subject: Accessing data from constructor
Message-Id: <1751b2b5.0210192317.580b3ea3@posting.google.com>

Hello everyone,

I've encountered some problems when I was working on the OOP part of
my program.

I have 3 datamembers, a 2D-array(@myarray) and two arrays (@row,
@col).
       1 method(so far) to do the print screen.

1) I've tried to put @myarray, @row and @col above the "new"
constructor and also

2) put them within the {} of "my $self = {_______}", like this
    my $self = {@myarray};


but they all give me the compiling error as follow: 

>> Global symbol "@myarray" requires explicit package name at
mainScreen.pm.
>> Global symbol "@row" requires explicit package name at
mainScreen.pm.
>> Global symbol "@col" requires explicit package name at
mainScreen.pm.

I believe that this is the reason why my redrawScreen() method won't
be able to access all my datamembers.

-------------------------------------------------------------
#! /usr/bin/perl -w

use strict;
package mainScreen;

sub _MYARRAY;
sub _ROW;
sub _COL;

sub new
{
    my $class = shift;
    my $self = {};
    my @myarray = shift;
    my @row = shift;
    my @col = shift;

    @myarray = (' ' x 51) x 21;

    @row = qw{ 1 1 1 1 1 1 1 2 4 6 8 10 12 14 15 15 15 15 15
               15 15 14 12 10 8 6 4 2 7 6 5 4 7 6 5 4 9 10 11
               12 9 10 11 12 1 2 3 4 12 13 14 15 15 14 13 12
               4 3 2 1 };
    @col = qw{ 12 15 18 21 24 27 30 32 32 32 32 32 32 32 30
               27 24 21 18 15 12 10 10 10 10 10 10 10 19 17
               15 13 23 25 27 29 19 17 15 13 23 25 27 29 6 5
               4 3 3 4 5 6 36 37 38 39 39 38 37 36 };

    for my $k (0..59){
        substr($myarray[$row[$k]],$col[$k],1) = 'O';
    }
    substr($myarray[2], 44, 5) = "Hello";

    bless ($self, $class);        
    return $self;
}

sub redrawScreen
{
    my @myarray = shift;
    for my $r (0..20) {
        print "$myarray[$r]\n";
    } 
}
1;
--------------------------------------------------------------

I've tried different coding like using _initialize. #example from
programming perl
but that's still doesn't work.

could you mind help me for this?

Thanks for you help.

Kit


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

Date: 20 Oct 2002 12:39:39 GMT
From: "James E Keenan" <jkeen@concentric.net>
Subject: Re: Accessing data from constructor
Message-Id: <aou86b$emi@dispatch.concentric.net>


"kit" <manutd_kit@yahoo.com> wrote in message
news:1751b2b5.0210192317.580b3ea3@posting.google.com...
> Hello everyone,
>
> I've encountered some problems when I was working on the OOP part of
> my program.
>
> I have 3 datamembers, a 2D-array(@myarray) and two arrays (@row,
> @col).
>        1 method(so far) to do the print screen.
>
> 1) I've tried to put @myarray, @row and @col above the "new"
> constructor and also
>
> 2) put them within the {} of "my $self = {_______}", like this
>     my $self = {@myarray};
>
>
> but they all give me the compiling error as follow:
>
> >> Global symbol "@myarray" requires explicit package name at
> mainScreen.pm.
> >> Global symbol "@row" requires explicit package name at
> mainScreen.pm.
> >> Global symbol "@col" requires explicit package name at
> mainScreen.pm.
>
> I believe that this is the reason why my redrawScreen() method won't
> be able to access all my datamembers.
>
> -------------------------------------------------------------
> #! /usr/bin/perl -w
>
> use strict;
> package mainScreen;

The path to the perl executable should be set in the calling script, not in
the module.  A better way to start the module would be:

package mainScreen;
use strict;
use warnings;

>
> sub _MYARRAY;
> sub _ROW;
> sub _COL;
>
If you check out modules in the core distribution or on CPAN, you'll find
that in 99.99% of the cases, the first subroutine declared is the
constructor.  There's no reason to declare these 3 at this point.  The
underscore to indicate a routine private to the module is good Perl style;
the ALLCAPS are not.  (ALLCAPS generally indicate something VERY SPECIAL to
Perl like BEGIN, DESTROY or END.)

And since you don't call these subs anywhere in the submitted code, why
include them at all?

> sub new
> {
>     my $class = shift;
>     my $self = {};
>     my @myarray = shift;
>     my @row = shift;
>     my @col = shift;

Arrays need to be passed to the constructor by reference.  As coded, you're
merely shifting 1 value from the first list in the argument list and placing
that in @myarray, shifting the 2nd value from the first list and placing it
in @row, etc.

>
>     @myarray = (' ' x 51) x 21;
>
What was the point of trying to get values for @myarray from the argument
list if you're immediately re-assigning new values to it inside the
constructor.

>     @row = qw{ 1 1 1 1 1 1 1 2 4 6 8 10 12 14 15 15 15 15 15
>                15 15 14 12 10 8 6 4 2 7 6 5 4 7 6 5 4 9 10 11
>                12 9 10 11 12 1 2 3 4 12 13 14 15 15 14 13 12
>                4 3 2 1 };

Wrong Perl syntax:  @row = qw(1 2 3);    # parens, not braces

Given the errors above, I would suggest that you go back and study how to
pass arguments to regular (non-OO) subroutines by reference before
attempting methods.  Figure out how to write code to achieve your objectives
using non-OO Perl.  Once you've got that down, you can try solving it in
OOP.




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

Date: 20 Oct 2002 12:39:40 GMT
From: "James E Keenan" <jkeen@concentric.net>
Subject: Re: Accessing data from constructor
Message-Id: <aou86c$emj@dispatch.concentric.net>


"kit" <manutd_kit@yahoo.com> wrote in message
news:1751b2b5.0210192317.580b3ea3@posting.google.com...
> Hello everyone,
>
> I've encountered some problems when I was working on the OOP part of
> my program.
>
> I have 3 datamembers, a 2D-array(@myarray) and two arrays (@row,
> @col).
>        1 method(so far) to do the print screen.
>
> 1) I've tried to put @myarray, @row and @col above the "new"
> constructor and also
>
> 2) put them within the {} of "my $self = {_______}", like this
>     my $self = {@myarray};
>
>
> but they all give me the compiling error as follow:
>
> >> Global symbol "@myarray" requires explicit package name at
> mainScreen.pm.
> >> Global symbol "@row" requires explicit package name at
> mainScreen.pm.
> >> Global symbol "@col" requires explicit package name at
> mainScreen.pm.
>
> I believe that this is the reason why my redrawScreen() method won't
> be able to access all my datamembers.
>
> -------------------------------------------------------------
> #! /usr/bin/perl -w
>
> use strict;
> package mainScreen;

The path to the perl executable should be set in the calling script, not in
the module.  A better way to start the module would be:

package mainScreen;
use strict;
use warnings;

>
> sub _MYARRAY;
> sub _ROW;
> sub _COL;
>
If you check out modules in the core distribution or on CPAN, you'll find
that in 99.99% of the cases, the first subroutine declared is the
constructor.  There's no reason to declare these 3 at this point.  The
underscore to indicate a routine private to the module is good Perl style;
the ALLCAPS are not.  (ALLCAPS generally indicate something VERY SPECIAL to
Perl like BEGIN, DESTROY or END.)

And since you don't call these subs anywhere in the submitted code, why
include them at all?

> sub new
> {
>     my $class = shift;
>     my $self = {};
>     my @myarray = shift;
>     my @row = shift;
>     my @col = shift;

Arrays need to be passed to the constructor by reference.  As coded, you're
merely shifting 1 value from the first list in the argument list and placing
that in @myarray, shifting the 2nd value from the first list and placing it
in @row, etc.

>
>     @myarray = (' ' x 51) x 21;
>
What was the point of trying to get values for @myarray from the argument
list if you're immediately re-assigning new values to it inside the
constructor.

>     @row = qw{ 1 1 1 1 1 1 1 2 4 6 8 10 12 14 15 15 15 15 15
>                15 15 14 12 10 8 6 4 2 7 6 5 4 7 6 5 4 9 10 11
>                12 9 10 11 12 1 2 3 4 12 13 14 15 15 14 13 12
>                4 3 2 1 };

Wrong Perl syntax:  @row = qw(1 2 3);    # parens, not braces

Given the errors above, I would suggest that you go back and study how to
pass arguments to regular (non-OO) subroutines by reference before
attempting methods.  Figure out how to write code to achieve your objectives
using non-OO Perl.  Once you've got that down, you can try solving it in
OOP.





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

Date: Sun, 20 Oct 2002 07:56:51 -0500
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: Accessing data from constructor
Message-Id: <slrnar5a0j.aih.tadmc@magna.augustmail.com>

James E Keenan <jkeen@concentric.net> wrote:
> "kit" <manutd_kit@yahoo.com> wrote in message
> news:1751b2b5.0210192317.580b3ea3@posting.google.com...


>>     @row = qw{ 1 1 1 1 1 1 1 2 4 6 8 10 12 14 15 15 15 15 15
>>                15 15 14 12 10 8 6 4 2 7 6 5 4 7 6 5 4 9 10 11
>>                12 9 10 11 12 1 2 3 4 12 13 14 15 15 14 13 12
>>                4 3 2 1 };
> 
> Wrong Perl syntax:  @row = qw(1 2 3);    # parens, not braces


No, that is correct syntax. You didn't try it, did you?

You can choose just about any punctuation character you
like for the delimiters.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: Sun, 20 Oct 2002 10:02:08 +0200
From: Michele Dondi <bik.mido@tiscalinet.it>
Subject: Re: Controlling recursion depth with File::Find
Message-Id: <9kh2ru408chs2l8chvnail9i7i8msrlbqb@4ax.com>

On Fri, 18 Oct 2002 17:03:03 -0400, Benjamin Goldberg
<goldbb2@earthlink.net> wrote:

>Michele Dondi wrote:

>> >> Have I to count the number of directory separators?
>> >
>> >my $path = "/some/directory/path/";
>> >my $len;
>> >find sub {
>> >   my $depth = substr( $_, $len ) =~ tr!/!!;
>> >   return $File::Find::prune = 1 if $depth > $n;
>> >   # do rest of processing here.
>> >}, $path;

>> Of course the above code would need some enhancements to take into
>> account the numer of slashes in $path
>
>That's what the substr() does -- it skips the leading part of $_, for
>however long $path is.  That way, $depth only counts slashes in the part
>we've recursed into.

But then, shouldn't the second line of the code you supplied read
"my $len = length $path;"? Or am I missing something obvious?

[...]

>> For ease of use File::Find could just include a $File::Find::depth var
>> with the obvious meaning. It should be set to 0 at root dirs and
>> incremented when recursing into a subdirectory and decremented when
>> getting back to the parent directory.
>
>This sounds like a good idea.  Since File::Find is part of core perl,
>the people who maintain and upgrade it are the same folks as maintain
>and upgrade perl -- the people on the perl5porters mailing list -- so
>use the 'perlbug' program to send in your idea.

I'm trying it soon!

>> Also (my humble suggestion) the value of such an hypothetical var
>> could be assigned locally to the $. var so to be able to use a
>> statement like
>> 
>> print if 1 .. 3;
>
>I don't know about this... think about what happens if the directories
>are 4 levels deep... it stops printing when $depth is 3, then (silently)
>goes deeper, and backs up, but on it's way up, it won't print any of the
>filenames that are at a depth of 2 or 3, until it's gone all the way up
>to a directory of depth 1.

Agreed, I don't know why I wrote such a thing. (hint: may it be that I
completely forgot how .. works?!?)


Michele
-- 
Liberta' va cercando, ch'e' si' cara,
Come sa chi per lei vita rifiuta.
           [Dante Alighieri, Purg. I, 71-72]

I am my own country - United States Confederate of Me!
           [Pennywise, "My own country"]


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

Date: Sun, 20 Oct 2002 05:21:37 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Controlling recursion depth with File::Find
Message-Id: <3DB275A1.F560D691@earthlink.net>

Michele Dondi wrote:
> 
> On Fri, 18 Oct 2002 17:03:03 -0400, Benjamin Goldberg
> <goldbb2@earthlink.net> wrote:
> 
> >Michele Dondi wrote:
> 
> >> >> Have I to count the number of directory separators?
> >> >
> >> >my $path = "/some/directory/path/";
> >> >my $len;
> >> >find sub {
> >> >   my $depth = substr( $_, $len ) =~ tr!/!!;
> >> >   return $File::Find::prune = 1 if $depth > $n;
> >> >   # do rest of processing here.
> >> >}, $path;
> 
> >> Of course the above code would need some enhancements to take into
> >> account the numer of slashes in $path
> >
> >That's what the substr() does -- it skips the leading part of $_, for
> >however long $path is.  That way, $depth only counts slashes in the
> >part we've recursed into.
> 
> But then, shouldn't the second line of the code you supplied read
> "my $len = length $path;"? Or am I missing something obvious?

 ... *smacks self on head*  Umm, yes.  I seem to have left that out.

[snip]
> >> Also (my humble suggestion) the value of such an hypothetical var
> >> could be assigned locally to the $. var so to be able to use a
> >> statement like
> >>
> >> print if 1 .. 3;
> >
> >I don't know about this... think about what happens if the
> >directories are 4 levels deep... it stops printing when $depth is 3,
> >then (silently) goes deeper, and backs up, but on it's way up, it
> >won't print any of the filenames that are at a depth of 2 or 3, until
> >it's gone all the way up to a directory of depth 1.
> 
> Agreed, I don't know why I wrote such a thing. (hint: may it be that I
> completely forgot how .. works?!?)

Quite possible -- it's *not* a very intuitive operator.

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

Date: Sun, 20 Oct 2002 12:37:10 +0200
From: peter pilsl <pilsl_use@goldfisch.at>
Subject: Re: DBI module INSERT command problem
Message-Id: <3db28764$1@e-post.inode.at>

Doug wrote:

> 
> Any comments, or suggestions would be appreciated, as I'm at wits end to
> figure out why I have this syntax error, especially considering an update
> with the same date variable in the same database and the same script works
> . Thanks
> 

For future problems I recommend the following:

if you have problems with a certain sql-statement, just print the statement 
and feed it to the console of your sql-server.
If the same error occures there its quite clear that its not a 
perl-problem, but a SQL-problem and maybe you'll get a more detailed 
errordescription :)

best,
peter

-- 
peter pilsl
pilsl_@goldfisch.at
http://www.goldfisch.at



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

Date: Sun, 20 Oct 2002 13:39:29 +0100
From: Gerry Hickman <gerry1@dircon.co.uk>
Subject: File::CounterFile and DEFAULT_DIR?
Message-Id: <3DB2A401.AF14CC1@dircon.co.uk>

I'm trying to use File::CounterFile cross-platform and I want to set the
default directory before the counter is created. I tried to do this (see
below), but it didn't work. The ENV variable is being ignored inside the
File::CounterFile module.

use strict;
use File::CounterFile;

$ENV{TMPDIR} = "/some/folder";

print "DEFAULT_DIR is ", $File::CounterFile::DEFAULT_DIR,"\n"; #prints
"/usr/tmp"

# my $c = new File::CounterFile "COUNTER", "aa00";
# ...

-- 
Gerry Hickman (London UK)


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

Date: 20 Oct 2002 04:51:11 +0800
From: Dan Jacobson <jidanni@dman.ddts.net>
Subject: gave a2p, s2p a one-liner, want one-liner back
Message-Id: <87bs5q40g0.fsf@jidanni.org>

For me, the a2p and s2p scripts have got it all wrong: If I give it a
one liner, I want back a one liner, otherwise it means perl is
inferior and I will go looking for a a2python etc. converter [any?]
$ echo '{print $5}'|a2p|wc -l
     16
BTW, the version is
$ a2p -v
Unrecognized switch: -v
$ a2p -V
Unrecognized switch: -V
$ a2p --help
[hangs]
$ a2p -?
Unrecognized switch: -?

Never mind the version then. a2p and s2p should add a switch to
produce terse one liners for "perl -wlpe" etc.
-- 
http://jidanni.org/ Taiwan(04)25854780


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

Date: Sun, 20 Oct 2002 07:50:51 -0500
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: gave a2p, s2p a one-liner, want one-liner back
Message-Id: <slrnar59lb.aih.tadmc@magna.augustmail.com>

Dan Jacobson <jidanni@dman.ddts.net> wrote:

> For me, the a2p and s2p scripts have got it all wrong: If I give it a
> one liner, I want back a one liner, 

> a2p and s2p should add a switch to
> produce terse one liners for "perl -wlpe" etc.


Let us know when you have the patch ready.

:-)


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: Sun, 20 Oct 2002 12:23:32 GMT
From: chris <chris@home.com>
Subject: Re: How to parse command line keywords?
Message-Id: <us75ru4um7dmgv44hf82d66qpq7b2m866a@4ax.com>

On Sat, 19 Oct 2002 22:58:02 -0500, tadmc@augustmail.com (Tad
McClellan) wrote:

>You can put them into a hash easily enough without any modules:
>
>-------------------------------------------
>#!/usr/bin/perl
>use warnings;
>use strict;
>
>my %opt;
>while ( $_ = shift ) {
>   my($name, $value) = split /=/;
>   $opt{$name} = $value;
>}
>
>print "$_ ==> $opt{$_}\n" for sort keys %opt;
>-------------------------------------------
>

I used the sample provided, did a sanity check for split function.
Thank you for your help. 


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

Date: Sun, 20 Oct 2002 04:40:17 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: IO::Handle::setvbuf not implemented on this architecture.
Message-Id: <3DB26BF1.C17552B5@earthlink.net>

Antwan Reijnen wrote:
> 
> Hi all,
> 
> I am experiencing problems while trying to run this Perl code on
> Redhet 8.0. It worked before on Redhat 7.2 / 7.3:
> 
> STDOUT->setvbuf($nothing_here, _IONBF, 0)
> 
> It complains: IO::Handle::setvbuf not implemented on this
> architecture.
> 
> My uname -a:
> 
> Linux twanus 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386
> GNU/Linux
> 
> My perl -v:
> 
> This is perl, v5.8.0 built for i386-linux-thread-multi
> 
> Where or how should I look for an answer? Is it a faulty or missing C
> library, or is it a Perl problem?

The problem is likely because your C library doesn't supply a setvbuf
function.  This isn't something *wrong* with the C library... it's
entirely optional for your C library to implement that, and it chose not
to.

You can probably workaround this by doing either:
   binmode(STDOUT, ":raw");
or:
   binmode(STDOUT, ":unix");
If you really and truly want the functionality that setvbuf with _IONBF
would provide.

However, you'd probably be better off doing just:
   STDOUT->autoflush(1);

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

Date: Sun, 20 Oct 2002 04:59:28 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Making a server both standalone and tcpd
Message-Id: <3DB27070.F78D413B@earthlink.net>

Brian T Glenn wrote:
> 
> I am writing a server program that I would like to have the ability to
> switch between having the program do its own sockets and having just
> use STDIN/STDOUT for use with tcp wrappers.

So, what you need to do is detect if STDIN/STDOUT are already sockets
(presumably created by inetd), and then branch based on that result.

   our ($dyndns, %opt);

   # make this the session leader
   POSIX::setsid() or die "Cannot setsid";

   {  defined(my $pid = fork) or die "Cannot fork: $!";
      exit if $pid;
   }

   {  open( my($pid), ">>/var/run/dyndnsd.pid") or last;
      print $pid $$, "\n";
   }

   if( -s \*STDIN ) {
      # STDOUT is also a socket, but should be
      # the same socket that we have as STDIN.
      $dyndns->sock(\*STDIN);
      $dyndns->HandleConnection();
      exit;
   }

   my $dyndns_server = IO::Socket::INET->new(
      Reuse => 1,
      LocalPort => $opt{port},
      Listen => SOMAXCONN,
   ) or die "Error creating listening socket: $@";

   while( my $dyndns_client = $dyndns_server->accept() ) {
      $dyndns->sock($dyndns_client);
      $dyndns->HandleConnection();
      close $dyndns_client;
   }

   die "Error in accept: $!";

   __END__
[untested]

PS: Note how I try and avoid having my code too deeply nested.  It makes
it much more readable.

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

Date: Sun, 20 Oct 2002 10:01:59 +0200
From: Michele Dondi <bik.mido@tiscalinet.it>
Subject: Re: Need advice on a project (wrt to tie'ing to a file and general strategy)
Message-Id: <26l2rusd9f3jtgqk85d85lln73mvltolu8@4ax.com>

On Fri, 18 Oct 2002 22:41:39 -0700, "Tan Nguyen" <nospam@nospam.com>
wrote:

>As pointed out in the previous post, there's Digest::MD5 on CPAN for your
>need. However, this beast is very slow (not because of Perl, it's the
>algorithm), but good to bring the probability of collision of two distinct
>file close to zero.

Don't laugh, but I seem to remember (not sure myself) that actually I
had chosen md5sum for some "ease of use" due to its fixed-length
output wrt, e.g. 'cksum'.

>If you don't mind the chance of two distinct files with the same filename
>and checksum, and like to speed up your checksum computation significantly,
>you might consider using CRC32. Correct me if I'm wrong, the collision
>probability of CRC32 is 2^(-32) which is approximately one out of 4 billion
>trials. Might be good enough for you application.

Indeed it would be good enough for my application. Now is there a
CRC32 module for perl? (OK, I'll search CPAN...)

>If you like to keep things in memory, you might want to give an estimate on
>how much memory you need to hold the whole thing. This varies widely
>depending on the average length of the filenames, average length of string
>of size of files and the number of files. (I assume that you'd like to keep
>a hash keyed on the filesize with values being filenames), plus a fair

I was rather thinking of a hash keyed on the filesize with values
being references to arrays whose first entries are filenames and the
second ones, if present, are the cksums.

And I would keep those entries that have a checksum setting the
filename to "" (multiple ones thus collapsing into a single one) for
subsequent use, as I explained in the previous post.

>estimate = number of files * (average length of filenames + average length
>of string of size of files) + 30 % extra (Perl and checksum computation).

I have total sum of (length of filenames + length of string of size of
files) = 6334Kb in one particular test.


Michele
-- 
Liberta' va cercando, ch'e' si' cara,
Come sa chi per lei vita rifiuta.
           [Dante Alighieri, Purg. I, 71-72]

I am my own country - United States Confederate of Me!
           [Pennywise, "My own country"]


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

Date: Sun, 20 Oct 2002 03:51:57 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: processing lines in pairs
Message-Id: <3DB2609D.CE85DB16@earthlink.net>

hymie! wrote:
[snip]
> In short, having read
> filename1 <tab> description1
> filename2 <tab> description2
> 
> I output something like this:
> <tr><td>filename1</td><td>description1</td><td>filename2</td></tr>
> <tr><td>         </td><td>description2</td><td>         </td></tr>
> 
> Which works fine as long as I guarantee that my lines are in pairs.
[snip]

The best solution I can think of is to not use while(<INDEX>) for
reading lines, but instead use something like this:

   my $buffer = "";
   my %escapes = ( "\n" => "", "n", "\n" );
   my $line_re = qr/(?s:\\.|[^\\\n])*\n/;
   while(sysread INDEX, $buffer, 8192, length $buffer) {
      # see if we have two whole lines (possibly with
      # escaped newlines in them).
      s/^($line_re)($line_re)// or next;

      # move the two lines from the dollar-digit variables
      # into normal variables.
      my ($line1, $line2) = ($1, $2);

      # unescape the two lines.
      $line =~ s/\\(.)/
         my $x = $escapes{$1};
         defined($x) ? $x : $1;
      /sge for $line1, $line2;

      # parse them.
      my ($file1, $text1) = pictureline($line1);
      my ($file2, $text2) = pictureline($line2);
      .... stuff ...

      # try another s/// before doing another sysread.
      redo;
   }
   # deal with anything left in $buffer.

[untested]

This is far superior over slurping in the whole file, but at the same
time, gives you just as much control over how the data is parsed and
dealt with.

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

Date: 20 Oct 2002 00:45:58 -0700
From: p76e160a4@hotmail.com (Peter Erl)
Subject: Re: References to substrings
Message-Id: <9fc0467f.0210192345.34395ef6@posting.google.com>

Tina Mueller <usenet@tinita.de> wrote in message news:<aos4fg$p4bgs$1@fu-berlin.de>...
> Peter Erl <p76e160a4@hotmail.com> wrote:
> 
> > I have a large blob of readonly data that I want to process as 
> > records without actually creating the records, ie a split
> > operation that returns an array of references to the original
> > data rather than a new list:
>  
> > $data = "sdklfjsdkfj\ndkdfg\ndfjkgdgjk\n";
> > @refs = splitref(/\n/, $data);
> > print "yes\n" if (\$data == $refs[0]);
> 
> i actually don't understand what you want, but the subject
> made me think about:
> my $x = \substr($string, 1,3);
> 
> you can now print $$x and also change it, and then
> the original string will be changed.
> 
> is that what you wanted?

It's close - it's the approach I originally took but I couldn't
get it to work; after some more experimentation I think I'm having
some sort of scoping problem but I don't know enough to fix it.

I have a bunch of programs that generate large datafiles.  When the
files have been created, a file descriptor is passed to a perl
script for some analysis.  As well as processing the data file as
a single object, the script also needs to split the data with various
delimiters and perform other processing.  Using split() results in
copies being created of the data, needlessly exercising brk().  Since
the data is never modified, creating references to the original data
would seem to be the best way to minimize thrashing.

The current code looks something like:

$size = (stat(STDIN))[7];
sysread(STDIN, $data, $size, 0);
for ($i = 0; $i < $size; $i = $n + 1) {
	$n = $size if (($n = index($data, $delim, $i)) < 0);
	push @ref, \substr($data, $i, $n - $i + 1);
}

The problem is that the substr ref always returns the same value, so
all of the refs in @ref point to the last record.  If I unwind the
loop:

$i = 0;
$n = index($data, $delim, $i);
push @ref, \substr($data, $i, $n - $i + 1);
$i = $n + 1;
$n = index($data, $delim, $i);
push @ref, \substr($data, $i, $n - $i + 1);
$i = $n + 1;

then $ref[0] and $ref[1] contain references to the first and second
records respectively so the concept seems sound, I just can't get it
to work inside the loop.

Can somebody put me out of my misery?

Thanks,
Pete.


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

Date: 20 Oct 2002 08:18:18 GMT
From: "Tassilo v. Parseval" <Tassilo.Parseval@post.rwth-aachen.de>
Subject: Re: References to substrings
Message-Id: <aotosa$qrv$1@nets3.rz.RWTH-Aachen.DE>

Also sprach Benjamin Goldberg:

> Bill Smith wrote:

>> Perl variables do not have a 'readonly' attribute.
> 
> Sure they do.   Consider what happens if you do:
>    *x = \"$x";
> and then try and modify $x.
> 
> Of course, this only works with $x being a package variable.  If you
> want to do it with a lexical variable (one created with my()), then you
> would need to use Devel::LexAlias, or Lexical::Alias.
> 
>    use Lexical::Alias;
>    my $x = ....;
>    alias_r \$x, \"$x";
> 
> Or, you could use the Scalar::Util module's readonly sub.

This only checks whether SVf_READONLY is set on the scalar and returns
true if that is the case.

As a side note: I'm still trying to find out how to make a hash readonly
XS-wise. It's easy with scalar and arrays (for arrays, this additionally
needs to be done for each scalar and reference that is stored inside).
But my hashes, even though succesfully getting the SVf_READONLY flag
(according to Devel::Peek), still behave pretty much like normal hashes.

Tassilo
-- 
$_=q!",}])(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus;})(rekcah{lrePbus;})(lreP{rehtonabus;})(rehtona{tsuJbus!;
$_=reverse;s/sub/(reverse"bus").chr(32)/xge;tr~\n~~d;eval;


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

Date: Sun, 20 Oct 2002 05:18:21 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: References to substrings
Message-Id: <3DB274DD.54EE0AA0@earthlink.net>

Peter Erl wrote:
> Tina Mueller wrote:
> > Peter Erl <p76e160a4@hotmail.com> wrote:
> >
> > > I have a large blob of readonly data that I want to process as
> > > records without actually creating the records, ie a split
> > > operation that returns an array of references to the original
> > > data rather than a new list:
> >
> > > $data = "sdklfjsdkfj\ndkdfg\ndfjkgdgjk\n";
> > > @refs = splitref(/\n/, $data);
> > > print "yes\n" if (\$data == $refs[0]);
> >
> > i actually don't understand what you want, but the subject
> > made me think about:
> > my $x = \substr($string, 1,3);
> >
> > you can now print $$x and also change it, and then
> > the original string will be changed.
> >
> > is that what you wanted?
> 
> It's close - it's the approach I originally took but I couldn't
> get it to work; after some more experimentation I think I'm having
> some sort of scoping problem but I don't know enough to fix it.
> 
> I have a bunch of programs that generate large datafiles.  When the
> files have been created, a file descriptor is passed to a perl
> script for some analysis.  As well as processing the data file as
> a single object, the script also needs to split the data with various
> delimiters and perform other processing.  Using split() results in
> copies being created of the data, needlessly exercising brk().  Since
> the data is never modified, creating references to the original data
> would seem to be the best way to minimize thrashing.
> 
> The current code looks something like:
> 
> $size = (stat(STDIN))[7];
> sysread(STDIN, $data, $size, 0);
> for ($i = 0; $i < $size; $i = $n + 1) {
>         $n = $size if (($n = index($data, $delim, $i)) < 0);
>         push @ref, \substr($data, $i, $n - $i + 1);
> }

Try:
   my $size = -s STDIN;
   read( STDIN, my($data), $size );
   for( my $search = 0; $search < $size; ) {
      my $start = $search;
      my $end = index( $data, $delim, $search );
      $end = length $data if $end < 0;
      eval q[
         push @ref, \substr( $data, $start, $end-$start );
      ];
      $search = $end + 1;
   }

> The problem is that the substr ref always returns the same value,

The problem is that the substr ref actually points to the opcode.

Since perl code is compiled once, the opcode doesn't change... you're
getting the same reference each time.

To see this, print out "@ref" directly, without dereferencing the
elements in it.

> so all of the refs in @ref point to the last record.
> If I unwind the loop:
> 
> $i = 0;
> $n = index($data, $delim, $i);
> push @ref, \substr($data, $i, $n - $i + 1);
> $i = $n + 1;
> $n = index($data, $delim, $i);
> push @ref, \substr($data, $i, $n - $i + 1);
> $i = $n + 1;
> 
> then $ref[0] and $ref[1] contain references to the first and second
> records respectively so the concept seems sound, I just can't get it
> to work inside the loop.

Here, you have two different substr ops.  Thus, you get two different
references.

To make it work inside the loop, you need to trick perl into seeing each
substr() that you do as a different op.  An eval STRING works nicely for
this.

> Can somebody put me out of my misery?

If your STDIN is a file, then you could probably use Tie::File on it,
with much less hassle.

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

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


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