in reply to Changing a variable which is a value of a hash

Store the reference in the hash, not the value.
#!/usr/bin/perl use warnings; use strict; my $test = 'test'; my %hash = ( t => \$test); # Store the reference. print join "\t", 'Before', ${ $hash{t} }, $test, $hash{t}, "\n"; my $change = 'changed'; ${ $hash{t} } = $change; # Change the value. print join "\t", 'After', ${ $hash{t} }, $test, $hash{t}, "\n"; __END__ Output: Before test test SCALAR(0x600078238) After changed changed SCALAR(0x600078238)
لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Replies are listed 'Best First'.
Re^2: Changing a variable which is a value of a hash
by jeffa (Bishop) on Apr 16, 2015 at 15:50 UTC

    From the OP: "#I just want to change $test to 'changed' not $hash{t} to $change"

    From that i believe that OP wants the output like so:

    _END__ Output: Before test test ... After test changed ...

    Which is boggling to me ...

    UPDATE: ... so i implemented it using tied hashes:

    #!/usr/bin/env perl package MagicHash; require Tie::Hash; our @ISA = qw(Tie::Hash); sub TIEHASH { bless {}, shift } sub STORE { my ($self, $key, $newval) = @_; $self->{$key} = {key=>$key, value=>[$newval,$$newval]}; } sub FIRSTKEY { my ($self) = @_; keys %{$self}; my $first_key = each %{$self}; return undef unless defined $first_key; return $self->{$first_key}->{key}; } sub FETCH { my ($self, $key) = @_; my ($is_ref) = $key =~ s/^\\//; return $is_ref ? $self->{$key}->{value}->[0] : $self->{$key}->{value}->[1] ; } sub NEXTKEY { my ($self, $nextkey) = @_; my $next_key = each %{$self}; return undef unless defined $next_key; return $self->{$next_key}->{key}; } package main; use strict; use warnings; use Data::Dumper; { my $test = 'test'; my $changed = 'changed'; my %hash = ( t => \$test ); print "Before: \$test = $test\n", Dumper \%hash; ${ $hash{t} } = 'changed'; print " After: \$test = $test\n", Dumper \%hash; } { my $test = 'test'; my $changed = 'changed'; tie my %hash, 'MagicHash'; %hash = ( t => \$test ); print "Tied Before: \$test = $test\n", Dumper \%hash; ${ $hash{'\t'} } = 'changed'; print "Tied After1: \$test = $test\n", Dumper \%hash; ${ $hash{'\t'} } = 'again'; print "Tied After2: \$test = $test\n", Dumper \%hash; $hash{'t'} = \'one more'; print "Tied After3: \$test = $test\n", Dumper \%hash; }
    The trick is to store the value of the var and the reference to it in an anonymous array reference and then use some identifier (i chose the backslash) to distinguish which one is needed at the time. Very silly stuff. Sorry 'bout that. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      I tried to implement my solution with tying, too. The difference to your solution is there's no need to indicate what value you want: Perl just does what you mean, as usually:
      #!/usr/bin/perl use warnings; use strict; { package MagicScalar; use Tie::Scalar; use parent qw( -norequire Tie::StdScalar ); use overload nomethod => \&stringify; sub TIESCALAR { my $class = shift; bless [], $class } sub STORE { my ($self, $value) = @_; $self->[0] = $value; } sub FETCH { my $self = shift; return $self } sub stringify { my $self = shift; return $self->[0] } } { package MagicHash; use Tie::Hash; use parent qw( -norequire Tie::StdHash ); sub STORE { my ($self, $key, $value) = @_; my $previous = $self->{$key}; if (ref $previous and $previous->isa('MagicScalar')) { $previous->STORE($value); } else { $self->{$key} = $value } } } tie my $test, 'MagicScalar'; $test = 'test'; tie my %hash, 'MagicHash'; %hash = (t => $test); print "Before $hash{t} $test\n"; my $change = 'changed'; $hash{t} = $change; print "After $hash{t} $test\n";
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re^2: Changing a variable which is a value of a hash
by benedicth (Initiate) on Apr 16, 2015 at 15:55 UTC
    Thank you!