Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^2: Changing a variable which is a value of a hash

by jeffa (Bishop)
on Apr 16, 2015 at 15:50 UTC ( #1123632=note: print w/replies, xml ) Need Help??


in reply to Re: Changing a variable which is a value of a hash
in thread Changing a variable which is a value of a hash

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)

Replies are listed 'Best First'.
Re^3: Changing a variable which is a value of a hash
by choroba (Cardinal) on Apr 16, 2015 at 19:15 UTC
    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";
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1123632]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (1)
As of 2023-09-25 02:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?