[comp.lang.perl] two perl questions

jbryans@beach.csulb.edu (Jack Bryans) (06/07/91)

The lib and emacs sub-directories each have a perldb.pl.  What's to choose
between 'em?

A while back there was a thread on forcing expression evaluation to be either
in scalar or array context.  I thought, "sure, I'll remember that".  Sigh!
What are some ways of forcing expr evaluation in array context?  A FAQ add'n,
perhaps?

Jack

 

Tom Christiansen <tchrist@convex.COM> (06/07/91)

From the keyboard of jbryans@beach.csulb.edu (Jack Bryans):
:A while back there was a thread on forcing expression evaluation to be either
:in scalar or array context.  I thought, "sure, I'll remember that".  Sigh!
:What are some ways of forcing expr evaluation in array context?  A FAQ add'n,
:perhaps?

It's not as straight-forward as using a scalar() on your expression, but
that's ok, because usually you don't need it.  Things that want to be in
an array context have no trouble getting there.  The list operators 
supply them, like:

    print /(foo) (bar)/;

If you assign to an array, you get one:

    @ary = /(foo) (bar)/;

You can also build a list and subscript it:

    $x = (/(foo) (bar)/)[$i]; # $i == 0 or 1
    @x = (/(foo) (bar)/)[@i]; # @i == (0,1) or (0,1)

Where would you like to force an array context?


--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
	    "Perl is to sed as C is to assembly language."  -me

merlyn@iWarp.intel.com (Randal L. Schwartz) (06/07/91)

In article <JBRYANS.91Jun6175843@beach.csulb.edu>, jbryans@beach (Jack Bryans) writes:
| A while back there was a thread on forcing expression evaluation to be either
| in scalar or array context.  I thought, "sure, I'll remember that".  Sigh!
| What are some ways of forcing expr evaluation in array context?  A FAQ add'n,
| perhaps?

Adding something to the FAQ won't force expr evaluation into an array context.
(And don't call me Shirley! :-)

But seriously...

Scalar can be forced with the scalar() operator, or by adding 0 or
concatenating a null string (depending on the type of value expected)
or assigning into a scalar.

Array can be forced by putting it into a list, or by assigning into an
array.

print +($a = "Just "),@b = ("another ", "Perl ", scalar("hacker,"))
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/

flee@cs.psu.edu (Felix Lee) (06/08/91)

>Array can be forced by putting it into a list, or by assigning into
>an array.

"putting it into a list" is not quite enough.  Perl has the real
problem that lists are indistinguishable from the comma operator.
	$x = (5, 10);
	print "$x\n";
	$x = @x = (5, 10);
	print "$x\n";

What if you want the last word from a split()?  This:
	$x = split(' ', 'a b c');
returns the number of split items.  This:
	@x = split(' ', 'a b c');
	$x = $x[$#x];
works, but requires a temporary array.

Do you think this works?
	$x = (0, split(' ', 'a b c'));
How about this?
	sub i1 { @_; }
	$x = &i1(split(' ', 'a b c'));
And this?
	sub i2 { return @_; }
	$x = &i2(split(' ', 'a b c'));
Do you understand the difference between &i1 and &i2?  I certainly
don't.

Let's hear it for experimental programming.
--
Felix Lee	flee@cs.psu.edu

Tom Christiansen <tchrist@convex.COM> (06/08/91)

Felix Lee wrote, quoting Randal:
:>Array can be forced by putting it into a list, or by assigning into
:>an array.
:
:"putting it into a list" is not quite enough.  Perl has the real
:problem that lists are indistinguishable from the comma operator.
:	$x = (5, 10);
:	print "$x\n";
:	$x = @x = (5, 10);
:	print "$x\n";

Quite so; that's is why I said ``put it in a list AND SUBSCRIPT IT.''

:What if you want the last word from a split()?  This:
:	$x = split(' ', 'a b c');
:returns the number of split items.  This:
:	@x = split(' ', 'a b c');
:	$x = $x[$#x];
:works, but requires a temporary array.

This requires no *named* temporary array:

    $x = (reverse split(' ','a b c'))[0];

Although to pull out the last piece of something, I'd use a regexp anyway:

    ($x) = 'a b c' =~ /(\S+)$/;
    $x = ('a b c' =~ /(\S+)$/)[0];

:Do you think this works?
:	$x = (0, split(' ', 'a b c'));

Yes.  Don't you?  Shouldn't it?

:How about this?
:	sub i1 { @_; }
:	$x = &i1(split(' ', 'a b c'));
:And this?
:	sub i2 { return @_; }
:	$x = &i2(split(' ', 'a b c'));
:Do you understand the difference between &i1 and &i2?  I certainly
:don't.

So, &i1 yields 3, whereas &i2 yield 'c'.  I won't claim to really
understand it, but here are some clues.  If you compile with -D1024,
you'll find that the assignments generate the same code, but the
two subroutines are very different: that 'return' incurs a good deal
of overhead, just enough to make it do what I'm assuming you want it to.

SUB main'i1 = {
    C_TYPE = EXPR
    C_ADDR = 0x800957c8
    C_NEXT = 0x0
    C_LINE = 8 (0x800957c8)
    C_OPT = CFT_EVAL
    C_FLAGS = (COND,TERM)
    C_EXPR = {
        OP_TYPE = ARRAY
        OP_LEN = 1
        [1]ARG_TYPE = STAB (unevaluated)
        [1]ARG_STAB = {
            STAB_NAME = main'_
        }
    }
    AC_STAB = NULL
    AC_EXPR = NULL
}

But here's the 2nd.  

SUB main'i2 = {
    C_TYPE = BLOCK
    C_ADDR = 0x80095b88
    C_NEXT = 0x0
    C_LINE = 9 (0x80095b88)
    C_LABEL = "_SUB_"
    C_OPT = CFT_FALSE
    C_FLAGS = (TERM)
    C_EXPR = NULL
    CC_TRUE = {
        C_TYPE = EXPR
        C_ADDR = 0x80095948
        C_NEXT = 0x0
        C_LINE = 9 (0x80095948)
        C_OPT = CFT_EVAL
        C_FLAGS = (COND,TERM)
        C_EXPR = {
            OP_TYPE = RETURN
            OP_LEN = 2
            [1]ARG_TYPE = WORD (unevaluated)
            [1]ARG_STAB = {}
            [2]ARG_TYPE = EXPR
            [2]ARG_FLAGS = (ARYOK)
            [2]ARG_ARG = {
                OP_TYPE = ARRAY
                OP_LEN = 1
                OP_FLAGS = (LISTISH)
                [1]ARG_TYPE = STAB (unevaluated)
                [1]ARG_STAB = {
                    STAB_NAME = main'_
                }
            }
        }
        AC_STAB = NULL
        AC_EXPR = NULL
    }
    CC_ALT = NULL
}

Notice in particular how the ARG_FLAGS in &i2 are ARYOK, and also
&i2's OP_FLAGS are LISTISH.  You don't see that in &i1.  

But I'm not particularly happy with this.  Larry, you must say
that this behavior is at the very least unexpected, eh?

:Let's hear it for experimental programming.

	Perl programming is an *empirical* science.  :-)

		Larry Wall in <10226@jpl-devvax.JPL.NASA.GOV>


--tom

--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time."