[22984] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 5204 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Jul 9 21:42:59 2003

Date: Wed, 9 Jul 2003 18:41:00 -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           Wed, 9 Jul 2003     Volume: 10 Number: 5204

Today's topics:
    Re: references => how not to destroy my data ? (Jan)
    Re: references => how not to destroy my data ? <ben.goldberg@hotpop.com>
        Regular expression imesh and timesheet <gallet@free.fr>
    Re: Regular expression imesh and timesheet (Helgi Briem)
    Re: Regular expression imesh and timesheet <gallet@free.fr>
    Re: Regular expression imesh and timesheet (Glenn Jackman)
    Re: Regular expression imesh and timesheet <gallet@free.fr>
    Re: Regular expression imesh and timesheet <coo_t2-NO-LIKE-SPAM@yahoo.com>
    Re: Regular expression imesh and timesheet <coo_t2-NO-LIKE-SPAM@yahoo.com>
    Re: Regular expression imesh and timesheet (Jay Tilton)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: 8 Jul 2003 10:38:07 -0700
From: jan_buys@hotmail.com (Jan)
Subject: Re: references => how not to destroy my data ?
Message-Id: <11971c2c.0307080938.3cd4fd70@posting.google.com>

Benjamin Goldberg <ben.goldberg@hotpop.com> wrote in message news:<3F09F096.2F7A074D@hotpop.com>...
> Jan wrote:
> > 
> > Hi,
> > 
> >  
> > $recordIndex = 0;
> > 
> > open (GROUPS, "<groupsfile.txt") or die "Cannot open $groupsFile\n";
> > while ($line = <GROUPS>)
> > {
> >    @juniorMembers = ();
> >    @seniorMembers = ();
> > #
> > # Snipped away code in which the two preceding arrays are populated
> > and in which
> > # which $group gets a valid value.  This code was tested and correct.
> > So for
> > # keeping things easy I'll leave this 'huge' part out...
> > #
> > 
> >     foreach $juniorMember(@juniorMembers)
> >       { push( @{$juniorArray}, $juniorMember) ; }
> >     foreach $seniorMember(@seniorMembers)
> >       { push( @{$seniorArray}, $seniorMember) ; }
> 
> What is put into $juniorArray and $SeniorArray before this?  If nothing,
> or if only [], then you could do:
> 
>    $juniorArray = \@juniorMembers;
>    $seniorArray = \@seniorMembers;
> 
> This of course will only work right if @juniorMembers and @seniorMembers
> are lexically scoped to the loop with my().  If you leave out the my(),
> and keep your old @juniorMembers = (); @seniorMembers = ();, then of
> course simply taking references to them won't work quite right. 
> Instead, you would have to do either what you have, or else one of:
>
>    push @$juniorArray, @juniorMembers;
>    push @$seniorArray, @seniorMembers;
> 
> > # Since I'm in while loop I try to store my data into an anonymous
> > # array by using a hard reference (e.g. $juniorArray)
> > 
> >     $myrecord = {  GROUP      => $group,
> >                    JUNIOR     => $juniorArray,
> >                    SENIOR     => $seniorArray };
> > 
> >      $database[$recordIndex++] = $myrecord;
> > }
> > 
> > # End code snippet.
> > 
> > Next thing I know, for each record I have in my 'database' array, when
> > dereferencing the arrays, about the same array contents.
> 
> Not just that... you probably have the same *arrays*, not just the same
> contents.

Correct !  I get the same arrays *and* their contents are wrong.  (see
further on...)

> 
> > I do know that I do overwrite my references to the arrays, but hoped
> > that would have been solved by storing these references in the
> > anonymous hash.
> > dumb, dumber...
> > 
> > So perl doesn't know the location of my 'junior' and 'senior' arrays
> > data anymore, I guess.  Can someone offer some advice on more proper
> > ways to come out of this while loop with the array data still intact ?
> 
> Rewrite the code something like this:
> 
>    use strict;   # always use strict!
>    use warnings; # always use warnings (or else, -w on #! line)!
>    open( my($groups), "<", "groupsfile.txt" )
>       or die "Couldn't open groupsfile.txt: $!";
>    my @database;
>    while( my $line = <$groups> ) {
>       my (@juniorMembers, @seniorMembers);
>       # put stuff in @juniorMembers and @seniorMembers from $line.
>       push @database, {
>          GROUP      => $group,
>          JUNIOR     => \@juniorMembers,
>          SENIOR     => \@seniorMembers,
>       };
>    }
>    close $groups;
>    # process @database
> 
> [untested]

I tested it for you ;-) (well, most part of it...), and you provided
the (sorry - a - ) correct solution.  I couldn't see anything wrong in
my code.  If possible (you helped me out already), could you explain
me or refer me to the proper documentation on where my solution went
wrong where yours is correct ?  I'm eager to learn about what seems to
be my misunderstanding of scope...

Thanks for helping out !
Jan


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

Date: Tue, 08 Jul 2003 22:36:48 -0400
From: Benjamin Goldberg <ben.goldberg@hotpop.com>
Subject: Re: references => how not to destroy my data ?
Message-Id: <3F0B7FC0.F63273F1@hotpop.com>

Jan wrote:
> Benjamin Goldberg wrote:
> > Jan wrote:
> > >
> > > Hi,
> > >
> > >
> > > $recordIndex = 0;
> > >
> > > open (GROUPS, "<groupsfile.txt") or die "Cannot open $groupsFile\n";
> > > while ($line = <GROUPS>)
> > > {
> > >    @juniorMembers = ();
> > >    @seniorMembers = ();
> > > #
> > > # Snipped away code in which the two preceding arrays are populated
> > > and in which
> > > # which $group gets a valid value.  This code was tested and correct.
> > > So for
> > > # keeping things easy I'll leave this 'huge' part out...
> > > #
> > >
> > >     foreach $juniorMember(@juniorMembers)
> > >       { push( @{$juniorArray}, $juniorMember) ; }
> > >     foreach $seniorMember(@seniorMembers)
> > >       { push( @{$seniorArray}, $seniorMember) ; }
> >
> > What is put into $juniorArray and $SeniorArray before this?  If nothing,
> > or if only [], then you could do:
> >
> >    $juniorArray = \@juniorMembers;
> >    $seniorArray = \@seniorMembers;
> >
> > This of course will only work right if @juniorMembers and @seniorMembers
> > are lexically scoped to the loop with my().

This means putting:

       my (@juniorMembers, @seniorMembers);

Just inside the while() loop, where you'd had:

       @juniorMembers = ();
       @seniorMembers = ();

It has the effect of making @juniorMembers and @seniorMembers *new*
arrays each time that the loop is entered... as opposed to re-using
the same old arrays again and again, but merely empying them out.

> > If you leave out the my(),
> > and keep your old @juniorMembers = (); @seniorMembers = ();, then of
> > course simply taking references to them won't work quite right.

The reason why simply taking references to them won't work right is
because you'll repeatedly be referencing the same two arrays, instead
of a couple of new arrays each time.

> > Instead, you would have to do either what you have, or else one of:
> >
> >    push @$juniorArray, @juniorMembers;
> >    push @$seniorArray, @seniorMembers;
> >
> > > # Since I'm in while loop I try to store my data into an anonymous
> > > # array by using a hard reference (e.g. $juniorArray)
> > >
> > >     $myrecord = {  GROUP      => $group,
> > >                    JUNIOR     => $juniorArray,
> > >                    SENIOR     => $seniorArray };
> > >
> > >      $database[$recordIndex++] = $myrecord;
> > > }
> > >
> > > # End code snippet.
> > >
> > > Next thing I know, for each record I have in my 'database' array, when
> > > dereferencing the arrays, about the same array contents.
> >
> > Not just that... you probably have the same *arrays*, not just the same
> > contents.
> 
> Correct !  I get the same arrays *and* their contents are wrong.  (see
> further on...)

Well, of *course* you get the same arrays -- you never did anything to
try and make *new* arrays.

Since you're re-using arrays where you should be making new ones, it's a
logical consequence that the contents aren't what you want.

> > > I do know that I do overwrite my references to the arrays, but hoped
> > > that would have been solved by storing these references in the
> > > anonymous hash.
> > > dumb, dumber...
> > >
> > > So perl doesn't know the location of my 'junior' and 'senior' arrays
> > > data anymore, I guess.  Can someone offer some advice on more proper
> > > ways to come out of this while loop with the array data still intact ?
> >
> > Rewrite the code something like this:
> >
> >    use strict;   # always use strict!
> >    use warnings; # always use warnings (or else, -w on #! line)!
> >    open( my($groups), "<", "groupsfile.txt" )
> >       or die "Couldn't open groupsfile.txt: $!";
> >    my @database;
> >    while( my $line = <$groups> ) {
> >       my (@juniorMembers, @seniorMembers);
> >       # put stuff in @juniorMembers and @seniorMembers from $line.
> >       push @database, {
> >          GROUP      => $group,
> >          JUNIOR     => \@juniorMembers,
> >          SENIOR     => \@seniorMembers,
> >       };
> >    }
> >    close $groups;
> >    # process @database
> >
> > [untested]
> 
> I tested it for you ;-) (well, most part of it...), and you provided
> the (sorry - a - ) correct solution.  I couldn't see anything wrong in
> my code.

Let's go over it again. [code simplified for clarity]

   while( $line = <GROUPS> ) {
      @juniorArrays = (); # set GLOBAL @juniorArrays to ()
      @seniorArrays = (); # set GLOBAL @seniorArrays to ()

      # fill in @juniorArrays and @seniorArrays.

      push @$juniorArray, @juniorArrays;
      push @$seniorArray, @seniorArrays;
      # append the contents of junior and senior arrays onto

      # the arrays referenced by the GLOBAL scalars of similar
      # names, possibly autovivifying those scalars into arrayrefs.

      # Note that we never did anything to replace $juniorArray
      # and $seniorArray with anything, to get rid of whatever was
      # left in them from the previous run through the while() loop!

      push @database, {
         junior => $juniorArray,
         senior => $seniorArray,
      };
      # put into @database the contents of $juniorArray and
      # $seniorArray... which are ALWAYS THE SAME!  Since we
      # never assign anything else to $juniorArray and $seniorArray,
      # it just puts the same two arrayrefs into @database again
      # and again!
   }

> If possible (you helped me out already), could you explain
> me or refer me to the proper documentation on where my solution went
> wrong where yours is correct ?  I'm eager to learn about what seems to
> be my misunderstanding of scope...

   perldoc perlref

Also, learn to use the perl debugger, and step through your code, and
print out the contents of the variables every so often.

-- 
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}


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

Date: Wed, 09 Jul 2003 17:53:11 +0200
From: TG <gallet@free.fr>
Subject: Regular expression imesh and timesheet
Message-Id: <3f0c3a5f$0$29680$626a54ce@news.free.fr>

hello,

i wan't to write a regular expression who match imesh but no match 
tIMESHeet. How can i do that ?



thank you




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

Date: Wed, 09 Jul 2003 16:15:17 GMT
From: helgi@decode.is (Helgi Briem)
Subject: Re: Regular expression imesh and timesheet
Message-Id: <3f0c3f51.1407641625@news.cis.dfn.de>

On Wed, 09 Jul 2003 17:53:11 +0200, TG <gallet@free.fr> wrote:

>i wan't to write a regular expression who match imesh but no match 
>tIMESHeet. How can i do that ?

You mean, match a single word only?

Use the boundary matching tag \b

print "Match!" if /\bimesh\b/;


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

Date: Wed, 09 Jul 2003 19:25:05 +0200
From: TG <gallet@free.fr>
To: Helgi Briem <helgi@decode.is>
Subject: Re: Regular expression imesh and timesheet
Message-Id: <3F0C4FF1.8000104@free.fr>

Helgi Briem wrote:
> On Wed, 09 Jul 2003 17:53:11 +0200, TG <gallet@free.fr> wrote:
> 
> 
>>i wan't to write a regular expression who match imesh but no match 
>>tIMESHeet. How can i do that ?
> 
> 
> You mean, match a single word only?
> 
> Use the boundary matching tag \b
> 
> print "Match!" if /\bimesh\b/;


not exactly, here an example of that i want :


imesh -> match
timessheet -> not match
myimeshsite -> match

Thank you



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

Date: 9 Jul 2003 17:34:13 GMT
From: xx087@freenet.carleton.ca (Glenn Jackman)
Subject: Re: Regular expression imesh and timesheet
Message-Id: <slrnbgokgm.e98.xx087@freenet10.carleton.ca>

TG <gallet@free.fr> wrote:
> hello,
> 
> i wan't to write a regular expression who match imesh but no match 
> tIMESHeet. How can i do that ?

A simple way is to just use 2 expressions.  There's surely a clever RE,
but it may not improve readability.

    if ($str =~ /imesh/i and $str !~ /timesheet/i) {
        # do something
    }


-- 
Glenn Jackman


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

Date: Wed, 09 Jul 2003 19:43:43 +0200
From: TG <gallet@free.fr>
To: Glenn Jackman <xx087@freenet.carleton.ca>
Subject: Re: Regular expression imesh and timesheet
Message-Id: <3F0C544F.50708@free.fr>

Glenn Jackman wrote:
> TG <gallet@free.fr> wrote:
> 
>>hello,
>>
>>i wan't to write a regular expression who match imesh but no match 
>>tIMESHeet. How can i do that ?
> 
> 
> A simple way is to just use 2 expressions.  There's surely a clever RE,
> but it may not improve readability.
> 
>     if ($str =~ /imesh/i and $str !~ /timesheet/i) {
>         # do something
>     }
> 
> 
sorry, but i want one expression



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

Date: Wed, 09 Jul 2003 18:10:43 GMT
From: ed <coo_t2-NO-LIKE-SPAM@yahoo.com>
Subject: Re: Regular expression imesh and timesheet
Message-Id: <eemogvcuqk0tpt2hltm4hd0s0f7mkjah2p@4ax.com>

On Wed, 09 Jul 2003 19:43:43 +0200, TG <gallet@free.fr> wrote:

>sorry, but i want one expression


Something like this should do:

$str =~ /(?<!t)imesh(?!eet)/;

I haven't tested it so I'm not sure it will work, but it's probably
close anyway.

Read this page under the "extended patterns" section:

http://www.perldoc.com/perl5.8.0/pod/perlre.html

--ed


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

Date: Wed, 09 Jul 2003 18:21:19 GMT
From: ed <coo_t2-NO-LIKE-SPAM@yahoo.com>
Subject: Re: Regular expression imesh and timesheet
Message-Id: <41nogvoelg2kosdm2q8bee86imh0vbhkfl@4ax.com>

On Wed, 09 Jul 2003 18:10:43 GMT, ed <coo_t2-NO-LIKE-SPAM@yahoo.com>
wrote:

>Something like this should do:
>
>$str =~ /(?<!t)imesh(?!eet)/;
>

Actually I didn't think that through.  
That probably won't work because you wanna be able to 
match timeshfoo or barimesheet right?

I don't know. I'd just use two expressions like Glenn. :)

--ed


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

Date: Wed, 09 Jul 2003 22:22:49 GMT
From: tiltonj@erols.com (Jay Tilton)
Subject: Re: Regular expression imesh and timesheet
Message-Id: <3f0c93b5.454010487@news.erols.com>

TG <gallet@free.fr> wrote:
: Glenn Jackman wrote:
: > TG <gallet@free.fr> wrote:
: > 
: >>i wan't to write a regular expression who match imesh but no match 
: >>tIMESHeet. How can i do that ?
: > 
: > A simple way is to just use 2 expressions.  There's surely a clever RE,
: > but it may not improve readability.
: > 
: >     if ($str =~ /imesh/i and $str !~ /timesheet/i) {
: >         # do something
: >     }
: > 
: sorry, but i want one expression

Why?

Do you have a subroutine that only accepts a regex argument?
Modifying that subroutine may be a better idea than trying to conform
to its expectations.

Are you planning to use a Perl regex in something besides a Perl
program?  You might get something you can't use.

Anyway,

    m/(?:(?<=(t))|(?<!t))imesh(?(1)(?!eet))/
         ^^^^^^^^^^^^^^^
         ^^^^^^^^^^^^^^^
Man, that's f'ed up, but it's the best I could come up with to make
the conditional pattern at the end work, without spending too much
time on it.

Two match operations is definitely the less nauseating approach.



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

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


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