pem@frankland-river.aaii.oz.au (Paul E. Maisano) (03/06/90)
Could someone please tell me how I can pass scalars by reference in the
same way arrays are. I know I can refer to $_[nnn] like its says in the
manual, but I would like to do something like:
sub foo {
local($x_by_ref_with_meaningful_name) = $_[0];
...
$x_by_ref_with_meaningful_name .= $foo; # update the original scalar
}
I tried this and it seemed to work on the first call only. Thereafter
it updated a global variable called $x_by_ref_with_meaningful_name.
Hopefully it's not a bug and I'm just doing something wrong.
It's happening on both SUN-3's and sparcstations, pl 12.
------------------
Paul E. Maisano
Australian Artificial Intelligence Institute
1 Grattan St. Carlton, Vic. 3053, Australia
Ph: +613 663-7922 Fax: +613 663-7937
Email: pem@aaii.oz.au UUCP: {uunet,mcsun,ukc,nttlab}!munnari!aaii.oz.au!pem
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/07/90)
In article <1220@frankland-river.aaii.oz.au> pem@frankland-river.aaii.oz.au (Paul E. Maisano) writes: : Could someone please tell me how I can pass scalars by reference in the : same way arrays are. I know I can refer to $_[nnn] like its says in the : manual, but I would like to do something like: : : sub foo { : local($x_by_ref_with_meaningful_name) = $_[0]; : ... : $x_by_ref_with_meaningful_name .= $foo; # update the original scalar : } : : I tried this and it seemed to work on the first call only. Thereafter : it updated a global variable called $x_by_ref_with_meaningful_name. That won't do what you want, because local($scalar) = @_ will always copy the value--it's how you turn call-by-reference into call-by-value in Perl. There are several ways for you to reference the original scalar: 1) Give up on giving a meaningful name and refer to $_[0]. 2) Invoke the C preprocessor and say #define meaningful_name _[0] 3) Use the type glob *name to pass in the symbol name: sub foo { local(*meaningful_name) = $_[0]; $meaningful_name .= pop(@meaningful_name); } &foo(*original_name); This last method is the most powerful, because you can pass anything that has a name in the symbol table, including filehandles, subroutines and formats. What you're really doing is passing in the symbol table entry for everything with that name and giving it a new name locally. Note that mechanism 1 can only give you references into an array's elements, while mechanism 3 can give you the array as a whole, so you can push, pop, shift, etc. on it. Larry
tneff@bfmny0.UU.NET (Tom Neff) (03/07/90)
In article <7293@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: > 3) Use the type glob *name to pass in the symbol name: ... > >This last method is the most powerful, because you can pass anything that has >a name in the symbol table, including filehandles, subroutines and formats. >What you're really doing is passing in the symbol table entry for everything >with that name and giving it a new name locally. Also note something not covered explicitly in the manual: This is the only way you can pass multiple arrays to a subroutine without effectively concatenating them into one amorphous array. For example if I want to be able to say @Questions = ("who", "what", "why"); @Answers = ("us", "this", "because"); @Weights = ("40", "35", "25"); $score = &process_one_quiz($pupil, @Questions, @Answers, @Weights); I cannot just say sub process_one_quiz { local ($p, @Q, @A, @W) = @_; ... } because @Q eats the rest of the @_ array including answers and weights. (The parameter list is ONE list.) But if I say sub process_one_quiz { local ($p, *Q, *A, *W) = @_; for $i ($[..$#Q) { print "$Q[$i],$A[$i],$W[$i]\n"; # (real work deleted) } } $score = &process_one_quiz($pupil, *Questions, *Answers, *Weights); then everything works right. Thus pass-by-reference can be an important tool for passing arrays even when the subroutine has no need to modify any elements. (Larry might want to mention this in the manual.) -- To have a horror of the bourgeois (\( Tom Neff is bourgeois. -- Jules Renard )\) tneff@bfmny0.UU.NET
pem@frankland-river.aaii.oz.au (Paul E. Maisano) (03/07/90)
Thanks for the explanation Larry. It's clear what I was doing wrong now. > : sub foo { > : local($x_by_ref_with_meaningful_name) = $_[0]; > : ... > : $x_by_ref_with_meaningful_name .= $foo; # update the original scalar > : } That was just a slip, what I meant to write was: sub foo { local(*x_by_ref_with_meaningful_name) = $_[0]; ... $x_by_ref_with_meaningful_name .= $foo; # update the original scalar } I had tried this. I was however calling foo incorrectly, as in &foo($real_name) instead of &foo(*real_name). The thing that threw me off track was that this actually works, once. I would be interested in knowing why this happens. ------------------ Paul E. Maisano Australian Artificial Intelligence Institute 1 Grattan St. Carlton, Vic. 3053, Australia Ph: +613 663-7922 Fax: +613 663-7937 Email: pem@aaii.oz.au UUCP: {uunet,mcsun,ukc,nttlab}!munnari!aaii.oz.au!pem