[comp.lang.perl] @array in scalar context

jv@mh.nl (Johan Vromans) (02/25/90)

This has bitten me a few times.

Is it defined that a scalar reference to an @array yields its last
element? 

Most notably: "if @array" depends on the last element of @array being
zero or not, while I would have expected it to be equivalent to 
"$#array >= $[" .

Johan

--
Johan Vromans				       jv@mh.nl via internet backbones
Multihouse Automatisering bv		       uucp: ..!{uunet,hp4nl}!mh.nl!jv
Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62944/62500
------------------------ "Arms are made for hugging" -------------------------

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/25/90)

In article <JV.90Feb24134508@mhres.mh.nl> jv@mh.nl (Johan Vromans) writes:
: This has bitten me a few times.
: 
: Is it defined that a scalar reference to an @array yields its last
: element? 
: 
: Most notably: "if @array" depends on the last element of @array being
: zero or not, while I would have expected it to be equivalent to 
: "$#array >= $[" .

It hasn't been officially defined.  It returns the last element merely
by analogy to the the comma operator.

Does anyone actually use this to get at the last value of an array?  If not,
we could easily change it to return the number of elements in the array.

	print "ok\n" if @array == $#array - $[ + 1;

Larry

tneff@bfmny0.UU.NET (Tom Neff) (02/26/90)

>: Is it defined that a scalar reference to an @array yields its last
>: element? 

In article <7165@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>Does anyone actually use this to get at the last value of an array?  If not,
>we could easily change it to return the number of elements in the array.
>
>	print "ok\n" if @array == $#array - $[ + 1;

I suspect some scripts use it to get at the ONLY value of an array, e.g.

	open(UNAME,"/bin/uname -s|");
	$uname = <UNAME>;
	close(UNAME);

In this case ($uname) = <UNAME> would have the same effect, but surely
people do use the shorthand form.

I would rather overload the length() operator in this case.
-- 
 1955-1975: 36 Elvis movies.  |  Tom Neff
 1975-1989: nothing.          |  tneff@bfmny0.UU.NET

tchrist@convex.COM (Tom Christiansen) (02/27/90)

In article <7165@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:

>Does anyone actually use this to get at the last value of an array?  If not,
>we could easily change it to return the number of elements in the array.
>
>	print "ok\n" if @array == $#array - $[ + 1;

Well, when I was young and foolish :-), I used to do this
	@foo = <*.*>;
	next if @foo =~ /\*/;
to check for no match on the glob.  Now wish the csh doing my globbing,
@foo isn't set on no match (which I like), and I get a coredump (which 
I don't much care for. :-).

The question is: what does @array do in a scalar context?  Larry 
proposes to set it true if the array is not empty.  If this is done,
I'd like to see a warning or error if it's used in a way that this doesn't
make sense, as in:

	@foo = 7;
	@foo =~ s/foo/bar;
	if (@foo =~ /something)

Of course, what I'd like better would be more work: a scalar reference
to an array is the same as the same scalar reference to each element of the 
array.  But along that road lies madness and APL, eh?

On arrays in scalar contexts, why doesn't this give any output:

    @a = ( 'red', 'yellow', 'green');
    print "has low\n" if grep(/low/,@a);

If I assign the grep to @b, I get the expected element 'yellow'.


--tom
--

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/28/90)

In article <100271@convex.convex.com> tchrist@convex.COM (Tom Christiansen) writes:
: The question is: what does @array do in a scalar context?  Larry 
: proposes to set it true if the array is not empty.  If this is done,
: I'd like to see a warning or error if it's used in a way that this doesn't
: make sense, as in:
: 
: 	@foo = 7;

Assigning a scalar to a list is currently legal, and the above means the same as

	@foo = (7);

The reason it's allowed is so that

	local($foo) = 7;

will work, since local($foo) is considered a list.

: 	@foo =~ s/foo/bar;
: 	if (@foo =~ /something/)

The last one should be allowed, since it's conceivable that you might
want to do pattern matching on the size of an array.

: Of course, what I'd like better would be more work: a scalar reference
: to an array is the same as the same scalar reference to each element of the 
: array.  But along that road lies madness and APL, eh?

With two ways (grep and foreach) to apply operations to array elements,
I don't think we need a third way.

: On arrays in scalar contexts, why doesn't this give any output:
: 
:     @a = ( 'red', 'yellow', 'green');
:     print "has low\n" if grep(/low/,@a);
: 
: If I assign the grep to @b, I get the expected element 'yellow'.

Grep was returning an undefined value in a scalar context.  It makes sense
for it to return the number of matches though, so I have made it do that.

Larry