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."