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

Hi

it's possible to alias a scalar to an element of a hash

DB<38> *y =\ $h{y} DB<39> $h{y}=666 DB<40> p $y 666 DB<41> $h{y}=42 DB<42> p $y 42

but I failed doing it the other way round. (i.e. $

Q1. Is it possible?

I could Tie::Hash the complete hash, but this would slow down all fetch operations on the hash, not only the aliased elements.

Q2. can I Tie::Scalar only a single element of a hash?

Thanks for insights! :)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

update

Sorry I'm stupid, my code already does what i wanted...

DB<53> $h{z}=111 DB<54> *z= \$h{z} DB<55> p $z 111 DB<56> $h{z}=222 DB<57> p $z 222 DB<58> $z=333 DB<59> p $h{z} 333

update

no not stupid, see my reply

Replies are listed 'Best First'.
Re: Aliasing hash-element and scalar?
by dave_the_m (Monsignor) on Sep 03, 2018 at 22:36 UTC
    From 5.22.0 onwards:
    use feature 'refaliasing'; no warnings 'experimental'; my ($x, $y, %h); \$h{foo} = \$x; \$y = \$h{foo}; $x = 99; printf "%d %d %d\n", $x, $y, $h{foo}; # prints 99 99 99

    Buts it's of course still an experimental feature.

    Dave.

      cool thanks! :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Aliasing hash-element and scalar? (Tie::Scalar)
by LanX (Saint) on Sep 03, 2018 at 19:21 UTC
    > Q2. can I Tie::Scalar only a single element of a hash?

    To answer my own question: Yes!

    use strict; use warnings; use 5.10.0; package Tie::Alias; require Tie::Scalar; our @ISA = qw(Tie::Scalar); use Data::Dump qw/pp dd/; sub FETCH { #pp \@_; my $obj =shift; return ${$obj->{alias}}; } sub STORE { #pp \@_; my $obj = shift; ${$obj->{alias}} = $_[0]; } sub TIESCALAR { #pp \@_; my $class = shift; my $alias = \ shift; my $obj = bless {alias => $alias}, $class; return $obj; } package main; my $h={}; my $y; tie $h->{y},'Tie::Alias', $y; $y=666; say $h->{y}; $y=42; say $h->{y}; $h->{y}=123; say $y; my $g={}; tie $g->{y},'Tie::Alias', $y; say $g->{y}; $h->{y}=999; say "$h->{y},$g->{y},$y"; $h->{x}="whatever"; say "$h->{x},$g->{x}";
    Use of uninitialized value in concatenation (.) or string at d:/Users/ +lanx/exp/tie_alias.pl line 72. 666 42 123 123 999,999,999 whatever,

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Aliasing hash-element and scalar? (Not Solved Yet)
by LanX (Saint) on Sep 03, 2018 at 18:38 UTC
    Sorry it's confusing, I'll try again.

    I managed to alias a scalar to one hash-element.

    But can I alias hash-elements from different hashes to the same scalar?

    i.e. when I change $x it mirrors in $h{x} and $g{x} and vice versa?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      I'm not really sure that Perl syntax allows you to alias hash entry scalars, but you can achieve the effect by using Data::Alias:

      use Data::Alias; use feature 'say'; $baz{'buf'} = 'Hello'; alias $foo{'bar'} = $baz{'buf'}; say $foo{'bar'}; $foo{'bar'} = 'World'; say $baz{'buf'}; $baz{'new'} = 'old'; say $foo{'old'}; __END__ Hello World Use of uninitialized value in say at ...
        Thanks.

        Background: I was thinking to emulate the Python OO system, and in that language a class attribute can be accessed thru the same mechanism like an instance attribute.

        Hence assigning self.class_attr will change the value for all objects, assigning to self.obj_attr only to that specific object.

        Data::Alias seems like a good idea, unless Python has optional magic __hooks__ to intercept a get/set on class_attr.

        In that case I should rather use Tie::Scalar.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice