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

It seems it's impossible to have a lexically scoped hash be an alias for the referent of a $hashref. I'm curious to find a way to do this avoiding the useless copying of values through `my %new = %$hashref'. Is an alias like that at least doable with package variables and typeglobs?

Replies are listed 'Best First'.
Re: Alias $hashref referent to a hash
by BrowserUk (Patriarch) on Oct 22, 2004 at 18:50 UTC

    #! perl -slw use strict; sub t{ ## Strict complient lexical access to a glob our %hash; ## Localise it for use as an alias ## to an inbound hash ref local *hash = shift; ## no need to dereference the hashref print "$_ => $hash{ $_ }" for keys %hash; } my %hash = ( 'A'..'Z' ); t( \%hash ); __END__ P:\test>test S => T A => B O => P W => X K => L Y => Z E => F Q => R M => N C => D I => J G => H U => V

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: Alias $hashref referent to a hash
by kvale (Monsignor) on Oct 22, 2004 at 18:03 UTC
    Lexical aliases seem to work fine:
    my %hash = (1 => 2, 3 => 4); my $ref = \%hash; my $alias = $ref; print "hash = ", %hash, "\n"; print "ref hash = ", %$ref, "\n"; print "alias hash = ", %$alias, "\n";
    prints
    hash = 1234 ref hash = 1234 alias hash = 1234
    What is the code you are having trouble with?

    -Mark

      Nah, that's still a reference. I want a %hash to be an alias to the referent, not a $scalar to keep the same reference.

      Thanks

        So you want to be able to do something like this:

        my $ref = {thing => 'value', otherthing => 'other'}; %alias_to_ref = ;# insert magical code here # to create a hash which will # still modify $ref $alias_to_ref{thing} = 'newvalue'; print $ref->{thing};

        And have that output 'newvalue'? If that is what you want, you probably could do it with a tied hash. See Below:

        #!/usr/local/bin/perl -w use strict; my($ash) = {thing => 'other', and => 'antoher'}; my(%hash); tie %hash, 'MyHash', $ash; $hash{thing} = 'new'; print $ash->{thing}."\n"; package MyHash; require Tie::Hash; @MyHash::ISA = qw(Tie::StdHash); sub STORE { my $me = shift; my $key = shift; $me->{$key} = shift; } sub TIEHASH { my $package = shift; my $ref = shift; return bless($ref, $package); }

        This outputs 'new'.

        May the Force be with you
Re: Alias $hashref referent to a hash
by hlen (Beadle) on Oct 22, 2004 at 19:42 UTC
    Thanks, folks, this is all very interesting. I also found that Lexical::Alias works for this.
    use Lexical::Alias ('alias'); my $ref = { a => 'b', c => 'd' }; my %hash; alias %{$ref}, %hash; print $ref->{'a'}; $hash{'a'} = 'e'; print $ref->{'a'};
    Yields:
    $ perl alias.pl b e
    The funny ordering, which goes against the common syntax in shells for the alias statement, got to me the first time. Nevertheless, these non modular solutions were what I wanted to know about.

    Cheers