cems2 has asked for the wisdom of the Perl Monks concerning the following question:
longer explanation of the problem:
Those familiar with type globs will recognize the following conventional use:
this will print "final".@foo = ("initial"); *bar = \@foo; $bar[0] = "final"; print @foo;
this inserts the referent to @foo into the array slot of the typeglob of bar, and thus @bar and @foo are refer to the same memory. thus the result
So far so good. Now I got into trouble here when I tried to use in combination with "strict vars", and incidentaly inside of a package.
Strict requires that I declare the variable @bar, and as near as I can tell there are three ways I can do this. "my @bar;" or "our @bar;" or "use vars qw/@bar/;" using "my @bar;" causes the incorrect, or rather unintended result, because as near as I can tell you cannot typeglob a lexical variable. What appears to happen is that the type glob creates a package variable @bar and links it to @foo, but then this variable is not accessible anymore as @bar since it is masked by the previously declared lexical variable. Thus the assingment $bar[0]=1 goes into the lexical @bar and not into @foo.
this prints "Initial"my @foo = ("initial"); use strict; my @bar; *bar = \@foo; $bar[0] = "final"; print @foo;
using "our @bar;" does achieve the desired outcome of printing "final" and making @bar and @foo linked. However, it does so apparently at the cost of creating a package global variable rather than a locally scoped variable. So the question is how do I get a locally scoped variable, and use a type glob? Actual use example of what I'm trying to do:
package wombat; our @bar = ("haha"); # this is going to get # accidentally clobbered use strict; sub A1 { my @foo = (1,2,3,4); return B2(3,\@foo); # pass in reference to @foo } sub B2 { my ($n,$foo) = @_; # now instead of always indexing $foo as a reference, # I will use a type glob # to allow me to access it as though it were an array. # @bar here is intended to be just a temporary convenience # variable name. But it accidentally collides with # a package global used elsewhere. # my @bar; # cannot do this, which would logically # be locally scoped as I want it to be # and avoid stepping on package globals. our @bar; # must do this instead, which because of #an accidental name collision with the # package global that is also called # "@bar", is going to have a sideeffect. *bar = $foo; # now do something with @bar # --this is just a trivial placeholder process @bar = map { sin($n+$_) } @bar; return $bar[0]+$bar[4]; # just a trivial placholder } print A1(); # prints the expected result print @bar; # but @bar is no longer "haha". # because it gets clobbered because # I could not control the scope of the typeglob
|
---|