blogical has asked for the wisdom of the Perl Monks concerning the following question:

Can you assign multiple variable names to a single data structure?
print "What I want" if (\@name1 eq \@name2);
How can I get What I want? Clarification: I want to avoid copying the data, and avoid using de-referencing notation to address the data. If I push something onto @name1, I want it to be avaiable on the tail of @name2.

Replies are listed 'Best First'.
Re: a reference by any other name...
by GrandFather (Saint) on Feb 20, 2006 at 01:41 UTC

    This may be what you want:

    use strict; use warnings; my @array1; my @array2; my $ref1 = \@array1; my $ref2 = \@array1; my $ref3 = \@array2; print "Maybe what you want\n" if $ref1 == $ref2; print "Not what you want\n" if $ref1 == $ref3;

    Prints:

    Maybe what you want

    Note that \@name1 returns a reference and I suspect what you want to know is if two references refer to the same object.


    DWIM is Perl's answer to Gödel
      Right- I want multiple names for the same data, and each would logically produce an identical reference using \. Otherwise I could just my $ref2 = $ref1; But I don't want to use de-referencing notation when I address the data, so I don't want to just use a copy of the reference. I especially don't want a copy of the data: my @array2 = @array1;

        I think there is a confusion of nomenclature here. \ returns a reference to something and that reference can be assigned to a scalar variable, which is then said to be a reference to the original something.

        A copy of the reference by using my $ref2 = $ref1; generates the same result as my $ref2 = \$something;. You seem to be talking about some sort of alias, somewhat like a *nix file system hard link. I am having trouble imagining a situation where you would require such a thing in Perl. Perhaps you need to show us a code snippet to illustrate the problem you are having?


        DWIM is Perl's answer to Gödel
Re: a reference by any other name...
by Aristotle (Chancellor) on Feb 20, 2006 at 02:02 UTC

    Are you looking for Data::Alias or Devel::LexAlias? That said, these modules are deep voodoo, not to be used in day-to-day coding, and I assume you just haven’t understood exactly how to use references, as GrandFather says. Some actual code sample would be helpful if you want better advice.

    Makeshifts last the longest.

      Devel::LexAlias looks like the sort of operation I'm looking for... of course, I don't regularly risk "flaming death" in the pursuit of laziness...
      If there isn't an appropriate, simple way to do this I'm going to be very surprised. I will be somewhat less surprised if I'm missing something obvious- it seems like such a simple request.
        If there isn't an appropriate, simple way to do this I'm going to be very surprised.

        You can do it pretty easily with package variables:

        @array1 = 0..9; *array2 = *array1; pop @array1; print "@array2\n"; pop @array2; print "@array1\n"

        But I think the flaming death risk is pretty high here, too, though for different reasons.

        Update: you can also use a similar technique to alias to a reference, though again the alias is a package variable, and as such carries all the associated caveats. Example:

        sub foo { my ($ref) = @_; local *nonref = $ref; pop @nonref; print "@$ref\n"; pop @$ref; print "@nonref\n"; } foo([ 0 .. 9 ]);

        Nope, no can do in Perl 5. Perl 6 will have aliasing in the language, but for Perl 5, Devel::LexAlias is the closest you get. It has always annoyed me as well, but there’s no way around it.

        Makeshifts last the longest.

Re: a reference by any other name...
by McDarren (Abbot) on Feb 20, 2006 at 01:41 UTC
    Update:Ignore this answer, as brian_d_foy pointed out - it's wrong. GrandFather has given you a more sensible answer :)

    erm, I'm not sure I understand your question - but anyway...

    Are you just trying to take a copy of an array and then compare it to the original?

    If that's the case, yes - you can do that. Consider the following:

    my @foo = qw(a b c d); my @bar = @foo; print "What I want\n" if (@foo eq @bar);
    Is that what you wanted?

      That won't work, of course, because the eq operates on scalars. An array in scalar context give the count of the number of elements, so as long as those arrays have the same number of elements, this code says they are the same. That' salmost never what you want. :)

      --
      brian d foy <brian@stonehenge.com>
      Subscribe to The Perl Review