Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Shorthand for($scalar) loops and resetting pos($scalar)

Reply
Thread Tools

Shorthand for($scalar) loops and resetting pos($scalar)

 
 
Clint Olsen
Guest
Posts: n/a
 
      11-12-2003
Hi:

I'm currently using 5.8.1, and I'm writing a lexer which operates on a
scalar that has the contents of the entire file. I'm using the usual
suspects (/gc and \G) in all of my patterns to remember where I was.

However, I've noticed a technique in Parse::Yapp which does the following:

LOOP: for ($scalar) {

/whitespace/ and next LOOP;
/pattern/ and this;
/patern1/ and that;
}

What exactly is the for() loop doing that's different than $_ = $scalar?

The documentation is pretty scant on this subject - conditions under which
pos() will be reset. Generally a for loop consists of an initialization, a
test, and an optional chunk to do at the end of the code BLOCK.

Thanks,

-Clint
 
Reply With Quote
 
 
 
 
Ben Morrow
Guest
Posts: n/a
 
      11-12-2003

Clint Olsen <(E-Mail Removed)> wrote:
> LOOP: for ($scalar) {
>
> /whitespace/ and next LOOP;
> /pattern/ and this;
> /patern1/ and that;
> }
>
> What exactly is the for() loop doing that's different than $_ = $scalar?


1. Giving you a loop to 'next' to,
2. localising $_,
3. aliasing $_ rather than simply assigning it: ie. modifying $_ in
the loop will modify $scalar outside it.

The loop could be rewritten

LOOP: {
local *_ = \$scalar;
...
}

but that's a little *too* incomprehensible, even for me .

This is quite a common idiom in Perl: it's sort-of like the 'with'
keyword in VB et al.

> The documentation is pretty scant on this subject - conditions under which
> pos() will be reset.


From perlop:

| A failed match normally resets the search position to the beginning
| of the string, but you can avoid that by adding the "/c" modifier
| (e.g. "m//gc"). Modifying the target string also resets the search
| position.

> Generally a for loop consists of an initialization, a test, and an
> optional chunk to do at the end of the code BLOCK.


That is a C-style for() loop, which is not much used in Perl and is
actually a while() loop in disguise . The for() loop above is the
*other* type of for() loop, which some people call a 'foreach' loop to
disambiguate.

Ben

--
I've seen things you people wouldn't believe: attack ships on fire off the
shoulder of Orion; I've watched C-beams glitter in the darkness near the
Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
Time to die. |-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-| http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Clint Olsen
Guest
Posts: n/a
 
      11-12-2003
On 2003-11-12, Ben Morrow <(E-Mail Removed)> wrote:
>
> 1. Giving you a loop to 'next' to,


Ok, makes sense. Although you don't really need the for keyword to do
that, as you have shown in later code.

> 2. localising $_,


I've never used local variables. The documentation says you should
generally avoid them in favor of lexically scoped variables.

> 3. aliasing $_ rather than simply assigning it: ie. modifying $_ in
> the loop will modify $scalar outside it.


How is that different than references? Sorry if my globbing/aliasing
knowledge is a bit sparse. I didn't start using Perl until version 5.X.

> The loop could be rewritten
>
> LOOP: {
> local *_ = \$scalar;
> ...


You don't mean $_?

>| A failed match normally resets the search position to the beginning
>| of the string, but you can avoid that by adding the "/c" modifier
>| (e.g. "m//gc"). Modifying the target string also resets the search
>| position.


Right, but it totally leaves out the case of when assigning a reference to
that scalar loses info or this "local" construct which appears to preserve
pos(). Obviously when you have a copy of a scalar, that scalar's pos()
should be 0 (or undef), but the conditions under which a copy is made is
obviously clouded in ths funky for() loop.

> That is a C-style for() loop, which is not much used in Perl and is
> actually a while() loop in disguise . The for() loop above is the
> *other* type of for() loop, which some people call a 'foreach' loop to
> disambiguate.


Yeah, it's as clear as mud I read page on perlsyn, and the for loop
does mention some similarity between for and foreach and while, but it
doesn't go any further than that.

-Clint
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      11-12-2003
Clint Olsen <(E-Mail Removed)> wrote:

> However, I've noticed a technique in Parse::Yapp which does the following:
>
> LOOP: for ($scalar) {
>
> /whitespace/ and next LOOP;
> /pattern/ and this;
> /patern1/ and that;
> }
>
> What exactly is the for() loop doing that's different than $_ = $scalar?



Nothing.

It just saves you from typing a lot of "$scalar =~" thingies.

ie:

$scalar =~ /whitespace/ and next LOOP;
$scalar =~ /pattern/ and this;
$scalar =~ /patern1/ and that;


> Generally a for loop consists of an initialization, a
> test, and an optional chunk to do at the end of the code BLOCK.



The "for" and "foreach" keywords are interchangeable in Perl,
so the above is the same as:

LOOP: foreach ($scalar) {

only with less typing.


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      11-12-2003
[posted & mailed (maybe?)]

On Wed, 12 Nov 2003, Clint Olsen wrote:

>On 2003-11-12, Ben Morrow <(E-Mail Removed)> wrote:
>>
>> 2. localising $_,

>
>I've never used local variables. The documentation says you should
>generally avoid them in favor of lexically scoped variables.


Yes, but there are some variables that CANNOT be lexically scoped; these
are generally punctuation variables, like $_ and @_ and $/.

>> 3. aliasing $_ rather than simply assigning it: ie. modifying $_ in
>> the loop will modify $scalar outside it.

>
>How is that different than references? Sorry if my globbing/aliasing
>knowledge is a bit sparse. I didn't start using Perl until version 5.X.


An alias is another name for a variable, whereas a reference is another
name for the LOCATION of a variable.

$foo = 'blah';
@foo = qw( fee fie foe fum );
*bar = \@foo;
$bar = 'boo';

print "$foo $bar[2]"; # blah foe

The second line makes @bar an alias for @foo; that is, any changes to @foo
change @bar, and vice-versa. If we had written

*bar = \*foo;

instead, then the print() line would have read 'boo foe', because ALL
'bar' variables would be aliases for ALL 'foo' variables. What's
important to realize here is that, because of the use of glob notation,
'bar' here is a global variable; it cannot be lexical, because lexical
variables are not related to each other -- they have no concept of a glob.

>> LOOP: {
>> local *_ = \$scalar;
>> ...

>
>You don't mean $_?


No, that would make $_ a REFERENCE to $scalar. This way makes it an alias
to $scalar. See above.

>>| A failed match normally resets the search position to the beginning
>>| of the string, but you can avoid that by adding the "/c" modifier
>>| (e.g. "m//gc"). Modifying the target string also resets the search
>>| position.

>
>Right, but it totally leaves out the case of when assigning a reference to
>that scalar loses info or this "local" construct which appears to preserve
>pos(). Obviously when you have a copy of a scalar, that scalar's pos()
>should be 0 (or undef), but the conditions under which a copy is made is
>obviously clouded in ths funky for() loop.


It's not funky, it's a Perl-style loop, also known as 'foreach'. I don't
know what you mean, though:

$x = "jeff";
pos($x) = 2;
for ($x) {
print pos($x), " " , pos($_), "\n"; # 2 2
}

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
Clint Olsen
Guest
Posts: n/a
 
      11-13-2003
I did get your email as well. Was there a problem initially sending it?

On 2003-11-12, Jeff 'japhy' Pinyan <(E-Mail Removed)> wrote:
>
> Yes, but there are some variables that CANNOT be lexically scoped; these
> are generally punctuation variables, like $_ and @_ and $/.


Right. I never tried to make them lexically scoped.

> $foo = 'blah';
> @foo = qw( fee fie foe fum );
> *bar = \@foo;
> $bar = 'boo';
>
> print "$foo $bar[2]"; # blah foe
>
> If we had written
>
> *bar = \*foo;
>
> instead, then the print() line would have read 'boo foe', because ALL
> 'bar' variables would be aliases for ALL 'foo' variables.


[some snipping]

Ahh, this is an excellent explanation, thanks.

> No, that would make $_ a REFERENCE to $scalar. This way makes it an alias
> to $scalar. See above.


Ok, makes much more sense now.

> It's not funky, it's a Perl-style loop, also known as 'foreach'. I don't
> know what you mean, though:
>
> $x = "jeff";
> pos($x) = 2;
> for ($x) {
> print pos($x), " " , pos($_), "\n"; # 2 2
> }


What I meant was it wasn't entirely obvious how $_ is being set in the
for() loop, and this is the key to preserving pos() for $x in and out of
the loop. Any attempt to assign $_ without using globbing wouldn't have
worked, right?

Thanks,

-Clint
 
Reply With Quote
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      11-13-2003
[posted & mailed]

On Thu, 13 Nov 2003, Clint Olsen wrote:

>I did get your email as well. Was there a problem initially sending it?


I couldn't be sure if the email address was valid (and was too lazy to
check out olsen.net).

>What I meant was it wasn't entirely obvious how $_ is being set in the
>for() loop, and this is the key to preserving pos() for $x in and out of
>the loop. Any attempt to assign $_ without using globbing wouldn't have
>worked, right?


Right; just copying the contents of $x to $y doesn't transfer $x's pos()
to $y.

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Shorthand operator for AND, NOT Archos Javascript 5 12-22-2011 09:54 AM
any() and all() shorthand castironpi@gmail.com Python 7 01-08-2008 04:26 AM
Loops with loops using html-template Me Perl Misc 2 01-12-2006 05:07 PM
foreach shorthand unspammable@gmail.com C++ 2 03-25-2005 10:38 PM
kiwi biz q_'n <== Teeline shorthand for question Quean Computer Support 2 12-23-2004 07:08 AM



Advertisments