# Question in Perl Arrays

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
Hi,

I am trying to understand how arrays work in scalar context. Here is
the question:

@a = (10,20,30,40,50);
@b = @a[0..3];
print "[@b] \n";

when I run this script, I am getting proper result i.e. o/p is: [10 20
30 40]
But when I do this change:
@a = (10,20,30,40,50);
@b = \$a[0..3];  # THIS LINE IS CHANGED
print "[@b] \n";

I get o/p as: [20]. why? why first element of the range operator is
ignored and 2nd element is assigned to @b. I am trying this just to
satisfy my curiosity.

Regards,

## Re: Question in Perl Arrays

Yogi wrote:

Your example below has nothing to do with scalar context.

Missing:

use strict;
use warnings;

Probably because \$a[0..3] is plain wrong. An array slice never starts
with '\$'.

If warnings had been enabled, Perl would have objected.

--
Email: http://www.gunnar.cc/cgi-bin/contact.pl

## Re: Question in Perl Arrays

Hi,
This is giving me same output (with warning ofcourse):
use strict;
use warnings;
my @b=3D();

my @a = (10,20,30,40,50);
@b = \$a[0..3];
print "[@b] \n";

If Array slice must not start with '\$', it should not give me 20 as o/
p.
-Regards

## Re: Question in Perl Arrays

Yogi wrote:

Yes it should.

C:\>perl -e "print 0..3"
0123
C:\>perl -e "print scalar (0..3)"
1

So 0..3 evaluates to 1 in a scalar context.
Therefore \$a[0..3] is \$a[1]
Presumably because array indexing uses a scalar index.

--
RGB

## Re: Question in Perl Arrays

RedGrittyBrick wrote:

Wrong. This is the flip-flop operator.
In scalar context with two constants,
it's matched against \$.

...
\$.= 2;
print "\$.\n";
print \$a[0..3], "\n"; # will return \$. if first operand (0) is false
...

Regards

M.

## Re: Question in Perl Arrays

Is there any simple document which explains how its working?  I tried
reading thru perldoc for .. operator, but am really confused between
list and scalar contexts?

Regards,

## Re: Question in Perl Arrays

On Thu, 17 Jul 2008 04:25:04 -0700, Yogi wrote:

The .. operator can be quite confusing when it comes to context. You
should read the perlop on "Range operators" for a detailed information
about it. As for contexts: @a[] evaluates its index under list context, \$a
[] does so under scalar context. In both cases, that makes a lot of sense
when you realize what they do.

Leon Timmermans

## Re: Question in Perl Arrays

Thanks all.  I started picking up bit of this context usage. :)
-Regards

## Re: Question in Perl Arrays

...

....

Probably not.  It is complex, so a simple document would be misleading.

Can you clarify the nature of your confusion?  Are you confused about how
.. behaves in each context, or how to determine which context it is in?

On the first point, I'm somewhat confused myself.  I've never fully
understand what the flip-flop mode does, but I understand enough to avoid
accidentally using it, so my confusion is safely sequestered.

On the second point, that is not an issue specific to "..", but a general
Perl issue.  In this case, it is intuitive to me that the subscript of
\$x[] is in scalar and @x[] is in list, but if you want to discover that
by experimentation, you can make a tattler function:
sub tattle { warn "wantarray: ", wantarray };

And then replace the ".." construct with an invocation of tattle to see

Xho

--
The costs of publication of this article were defrayed in part by the
this fact.

## Re: Question in Perl Arrays

Quoth xhoster@gmail.com:

It's designed for use with -n. Something like

perl -ne'/foo/../bar/ and print'

will print all the lines from 'foo' to 'bar', and

perl -ne'3../STOP/ and print'

will print from the third line up to one containing 'STOP'. It is the
same as the ',' operator in sed(1) and awk(1) (specifically, .. is like
awk's and ... like sed's) and was put into Perl for the benefit of
people used to those utilities.

Ben

--
"Faith has you at a disadvantage, Buffy."
"'Cause I'm not crazy, or 'cause I don't kill people?"
"Both, actually."
[ben@morrow.me.uk]

## Re: Question in Perl Arrays

BM> Quoth xhoster@gmail.com:
>>
>> On the first point, I'm somewhat confused myself.  I've never fully
>> understand what the flip-flop mode does, but I understand enough to avoid
>> accidentally using it, so my confusion is safely sequestered.

BM> It's designed for use with -n. Something like

BM>     perl -ne'/foo/../bar/ and print'

and i have used it before with while(<FH>) loops. it isn't dedicated to
-n.

the flip flop op is just a bistable value. it starts out as false (it
returns a false value) until the left side expression evaluates to
true. then it returns true until the right side expression evaluates to
true. the it reverts to false and testing the left side again.

so it keeps track of its state between its evaluations. that is why it
is called flip flop (after the single bit hardware memory cell that
remembers its state). bistable is also a good name as it is stable in
two ways, true and false and needs a trigger (one side or the other
evaluating to true at the right time.

note that .. only evaluates one side or the other based on its current
state.

and it is called range even in scalar context because a (the most?)
common use is to select a range of lines from a stream. it even has a
builtin test against \$. if either side is a literal number.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: Question in Perl Arrays

What about when there's three dots, "..."?

(This thread is shaping up to be a pretty good doc
on flip=flop, with contexts.)

THANKS!

David

## Re: Question in Perl Arrays

Quoth dkcombs@panix.com (David Combs):

I think perlop is pretty clear on that point, at least:

| [".."] can test the right operand and become false on the same
| evaluation it became true (as in awk), but it still returns true once.
| If you donâ€™t want it to test the right operand till the next
| evaluation, as in sed, just use three dots ("...") instead of two.  In
| all other regards, "..." behaves just like ".." does.

so given the input

FOOBAR
BAZ
BAR
QUUX

this

perl -ne'print if /FOO/../BAR/'

will print

FOOBAR

only, whereas this

perl -ne'print if /FOO/.../BAR/'

will print

FOOBAR
BAZ
BAR

that is, it ignores the fact that the 'start matching' line is also a
valid 'stop matching' line. That is the only difference between the two.

Ben

--
We do not stop playing because we grow old;
we grow old because we stop playing.
ben@morrow.me.uk

## Re: Question in Perl Arrays

Oh yeah, I vaguely know what its purpose is, but all the things about
when each test is executed, and .. versus ..., and \$. vs \$_, and whether
the state is attached to one particular line of code or is global, it all
just made my eyes glaze over.  So I decided I'd punt, and come back and
read the docs in more depth when/if I ever decided I actually needed to use
it.

Recently I wanted exactly the 3rd line after a given line (say, the one
containing "foo") over thousands of files.

I thought this would work:
fgrep -A3 -B-3 foo *.txt

Except fgrep stubbornly refuses to accept negative arguments to -B.
That almost tempted me to go back and read up on flip-flop again, but I
found another string that I could filter on (one that was unique to the
desired line out of the four lines returned by fgrep -A3 foo, but not
globally unique) before I actually bit the bullet.

Now that I have gone back and reread, I think this would work:

perl -lne '(/foo/../bar/) == 4 and print "\$ARGV\t\$_"' *.txt

But only because I found a string ("bar", here) that always occurs later
in each file to turn off the flip-flop, preparing it for the next file.

Hmm.

perl -lne '(/foo/..eof(ARGV)) == 4 and print "\$ARGV\t\$_"' *.txt

That seems to do it.  Well, now I know.

Xho

--
The costs of publication of this article were defrayed in part by the
this fact.

## Re: Question in Perl Arrays

>> Quoth xhoster@gmail.com:
>> >
>> > On the first point, I'm somewhat confused myself.  I've never fully
>> > understand what the flip-flop mode does, but I understand enough to
>> > avoid accidentally using it, so my confusion is safely sequestered.
>>
>> It's designed for use with -n. Something like
>>
>> perl -ne'/foo/../bar/ and print'
>>
>> will print all the lines from 'foo' to 'bar', and

x> Oh yeah, I vaguely know what its purpose is, but all the things about
x> when each test is executed, and .. versus ..., and \$. vs \$_, and whether
x> the state is attached to one particular line of code or is global, it all
x> just made my eyes glaze over.  So I decided I'd punt, and come back and
x> read the docs in more depth when/if I ever decided I actually needed to use
x> it.

\$_ has nothing to do with .. (it does matter if you use // as an
expression in your ..). the state of .. has to be local to the instance
of the op (not even the line of code). otherwise all hell would break
loose if two modules used .. at the same time. as for when the test
expressions are executed, it is easy to remember. left until true, then
right until true. all ... does is also test right immediately when left
becomes true so you can work on a range of one line.

x> Recently I wanted exactly the 3rd line after a given line (say, the one
x> containing "foo") over thousands of files.

x> I thought this would work:
x> fgrep -A3 -B-3 foo *.txt

x> Except fgrep stubbornly refuses to accept negative arguments to -B.
x> That almost tempted me to go back and read up on flip-flop again, but I
x> found another string that I could filter on (one that was unique to the
x> desired line out of the four lines returned by fgrep -A3 foo, but not
x> globally unique) before I actually bit the bullet.

x> Now that I have gone back and reread, I think this would work:

x> perl -lne '(/foo/../bar/) == 4 and print "\$ARGV\t\$_"' *.txt

x> But only because I found a string ("bar", here) that always occurs later
x> in each file to turn off the flip-flop, preparing it for the next file.

x> Hmm.

x> perl -lne '(/foo/..eof(ARGV)) == 4 and print "\$ARGV\t\$_"' *.txt

x> That seems to do it.  Well, now I know.

look into ack, a perl version of grep with many perlish and developer
features. it may support that and if not, patches welcome! in fact
boston.pm is working on a rewrite of the ack main loop to make it faster
and cleaner.

uri

--
Uri Guttman  ------  uri@stemsystems.com  --------  http://www.sysarch.com --
-----  Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

## Re: Question in Perl Arrays

Mirco Wahab wrote:

TFTC

--
RGB

## Re: Question in Perl Arrays

RedGrittyBrick wrote:

Oops, what's the meaning of that?

Consider:

...

my @arr = 0..999;    # some data
\$. = \$[;             # \$. to first array index

for (@arr) {
print "\$_\n" if 100..120;
++\$.
}

...

Regards

M.

## Re: Question in Perl Arrays

Mirco Wahab wrote:

It is an abbreviation of "Thanks For The Correction".

Sometimes I accidentally use abbreviations which are common in another
forum but rare in this one.

SFCC

--
RGB

## Re: Question in Perl Arrays

On Thu, 17 Jul 2008 11:31:28 -0400, Sherman Pendley wrote:

Because in scalar context it doesn't produce a range, but a flip-flop. It
returns 1 if the current line number (in the variable \$.) is equal to the
first number and continues to do so until the line number is equal to the
second number. This is a heritage from sed and awk.

Since he doesn't do any reading, \$. == 0, so it returns 1.

Returning its length is a property of arrays, *not a general feature of
list* or functions or builtins returning lists. m//, s///, qw//, qx//,
reverse, split, splice, split, sort, times, unpack, readdir, stat,
caller, get*/set*, localtime, gmtime and possibly a few more don't do so
either. In fact, I think grep and map are the only builtins that mimic
the behavior of arrays.

Leon Timmermans