in reply to Deletion of value in a multiple value assigned to a key

Using delete works for me. The code you show appears to be part of a Data::Dumper output without the variable name. Could it be that LOCKS is a key and not the name of your hash? This code demonstrates creating the hash, writing it to a file, recreating the hash from the file, deleting one sub-sub-key from the hash, writing the change back to the file again then recreating the hash again (I hold the file in a scalar rather than on disk just to keep things tidy).

use strict; use warnings; use 5.010; use Data::Dumper; my $hashFile; my $hashOutFH; my %HoH = ( LOCKS => { SCRIPT => { script1 => { params => [ qw{ a b c } ], shell => q{/bin/bash} }, script2 => { params => [ qw{ -v } ] }, }, }, ); open $hashOutFH, q{>}, \ $hashFile or die qq{open: > \ $hashFile: $!\n}; print $hashOutFH Data::Dumper->Dumpxs( [ \ %HoH ], [ qw{ *HoH } ] ); close $hashOutFH or die qq{close: > \ $hashFile: $!\n}; say q{File content after first write}; print $hashFile; say q{-} x 50; my %HoH1 = do { open my $hashInFH, q{<}, \ $hashFile or die qq{open: < \ $hashFile: $!\n}; my $str = <$hashInFH>; eval $str; %HoH; }; say q{New hash as read in from file}; print Data::Dumper->Dumpxs( [ \ %HoH1 ], [ qw{ *HoH1 } ] ); say q{-} x 50; delete $HoH1{ LOCKS }->{ SCRIPT }->{ script2 }; open $hashOutFH, q{>}, \ $hashFile or die qq{open: > \ $hashFile: $!\n}; print $hashOutFH Data::Dumper->Dumpxs( [ \ %HoH1 ], [ qw{ *HoH } ] ); close $hashOutFH or die qq{close: > \ $hashFile: $!\n}; say q{File content after key delete and second write}; print $hashFile; say q{-} x 50; my %HoH2 = do { open my $hashInFH, q{<}, \ $hashFile or die qq{open: < \ $hashFile: $!\n}; my $str = <$hashInFH>; eval $str; %HoH; }; say q{Second new hash read in from modified file}; print Data::Dumper->Dumpxs( [ \ %HoH2 ], [ qw{ *HoH2 } ] );

The output.

File content after first write %HoH = ( 'LOCKS' => { 'SCRIPT' => { 'script1' => { 'params' => [ 'a', 'b', 'c' ], 'shell' => '/bin/ba +sh' }, 'script2' => { 'params' => [ '-v' ] } } } ); -------------------------------------------------- New hash as read in from file %HoH1 = ( 'LOCKS' => { 'SCRIPT' => { 'script1' => { 'params' => [ 'a', 'b', 'c' ], 'shell' => '/bin/b +ash' }, 'script2' => { 'params' => [ '-v' ] } } } ); -------------------------------------------------- File content after key delete and second write %HoH = ( 'LOCKS' => { 'SCRIPT' => { 'script1' => { 'params' => [ 'a', 'b', 'c' ], 'shell' => '/bin/ba +sh' } } } ); -------------------------------------------------- Second new hash read in from modified file %HoH2 = ( 'LOCKS' => { 'SCRIPT' => { 'script1' => { 'params' => [ 'a', 'b', 'c' ], 'shell' => '/bin/b +ash' } } } );

I hope this is helpful.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Deletion of value in a multiple value assigned to a key
by Raj84 (Initiate) on Mar 21, 2011 at 00:55 UTC

    Thank you John for the reply. It is actually working in a multiple process environment. So the same hashfile is accessed by different process at the same time. I am posting a part of the code and algo for the rest.

    sub read { my ($device) = shift; &debugLock ("Locking $device",2); &lock_directory(); my $file = "$ENV{LOCKS_LOCKING_DIR}/$device"; # if we failed to open the file that was there if (!open(LFILE, "<$file")) { $::DEVICES{byname}{$device}{LOCKS}{LAST_MESSAGE} = "Couldn't open lock file $file"; &debugLock ("Unlocking $device",2); &unlock_directory(); return 0; } my @output; @output = <LFILE>; close (LFILE); my $tempIndex; for (my $index =0; $index <= $#output; $index++) { next if ($output[$index] !~ /^\(\).*\+/); chomp ($output[$index]); my ($data, $variable_name) = split /\+/, $output[$index]; my ($msg, $variable_value) = split /:/, $data; if ($variable_name =~ /SCRIPT/) { my %tempHash; for ($tempIndex = $index+1;$output[$tempIndex] !~ /^\(\)/ +&& $output[$tempIndex] !~ /^\*/; $tempIndex++) + { $output[$tempIndex] =~ s/^\s+//; my ($data1,$variable) = split (/\+/, $output[$tempInde +x]); my ($msg1,$param) = split (/:/, $data1); $tempHash{$msg1}=$param; } $::DEVICES{byname}{$device}{LOCKS}{SCRIPT}{$variable_value +}= \%tempHash; $index = --$tempIndex; } else { $::DEVICES{byname}{$device}{LOCKS}{$variable_name}= $variable_value; } } &unlock_directory(); return 1; } sub write { my $device = shift; &debugLock ("Locking $device",2); &lock_directory (); my $file = "$ENV{LOCKS_LOCKING_DIR}/$device"; if (!open(LFILE, ">$file")) { $::DEVICES{byname}{$device}{LOCKS}{LAST_MESSAGE} = "Couldn't write to lock file $file"; &debugLock ("Unlocking $device",2); &unlock_directory(); return 0; } print LFILE <<EOF; (hash update information) EOF &unlock_directory(); return 1; } sub delete { my $scriptTest = shift; foreach my $key (keys %{$::DEVICES{byname}{$device}{LOCKS}{SCRIPT}} +) { print "Delete Key <= $key \n"; $numScripts++; if ($key =~ /$scriptTest/) { $scriptName = $key; %tempHash = %{$::DEVICES{byname}{$device}{LOCKS}{SCRIPT}{$k +ey}}; } $userFlag++ if ($::DEVICES{byname}{$device}{LOCKS}{SCRIPT}{$key +}{USER} =~ /$args{USER}/) ; } if ($numScripts) { if ($userFlag > 1) { delete $::DEVICES{byname}{$device}{LOCKS}{SCRIPT}->{$script +Name}; } elsif ($userFlag == 0) { return (1, "The Lock File didnt find the values for the scr +ipt"); } else { (update required hash value) $::DEVICES{byname}{$device}{LOCKS}{USER} = $userString; delete $::DEVICES{byname}{$device}{LOCKS}{SCRIPT}->{$script +Name}; } $numScripts--; if ($numScripts) { $::DEVICES{byname}{$device}{LOCKS}{LAST_MESSAGE} = "Successfully free'd port lock on $device for $por +tsRemove"; my $status = &write_port_data($device); return ($status, "Successfully free'd the hash"); } else { # if there are no scripts in the device, i.e., no one is us +ing the device # I want to unlock the device completely. my $success =&unlock($args{DEVICE}, $args{FLAGS}, $args{USE +R}); return ($success, $::DEVICES{byname}{$args{DEVICE}}{LOCKS}{ +LAST_MESSAGE}); } } } sub createPort { (create tempHash) my %tempHash; $tempHash{A}=z; $tempHash{B}=y; $tempHash{C}=x; --- --- my $scriptName = "script1"; $::DEVICES{byname}{$device}{LOCKS}{SCRIPT}{$scriptName} = \%tempHas +h; my $status = &write_port_data ($device); return $status; }

    The following are the output

    The process 1: 20MAR2011 16h15m28s <============ read entry Read Key <= script1 Read Key <= script2 Read Key <= script3 20MAR2011 16h15m28s <============ read exit Delete Key <= script1 Delete Key <= script2 Delete Key <= script3 20MAR2011 16h15m28s <========== TIME IN WRITE Key <= script2 Key <= script3 20MAR2011 16h15m28s <==========End TIME IN WRITE The Process 2: 20MAR2011 16h15m38s <============ read entry Read Key <= script1 Read Key <= script2 Read Key <= script3 20MAR2011 16h15m38s <============ read exit Delete Key <= script1 Delete Key <= script2 Delete Key <= script3 20MAR2011 16h15m38s <========== TIME IN WRITE Key <= script1 Key <= script3 20MAR2011 16h15m38s <==========End TIME IN WRITE The Process 3: 20MAR2011 16h15m41s <============ read entry Read Key <= script1 Read Key <= script2 Read Key <= script3 20MAR2011 16h15m41s <============ read exit Delete Key <= script1 Delete Key <= script2 Delete Key <= script3 20MAR2011 16h15m41s <========== TIME IN WRITE Key <= script1 Key <= script2 20MAR2011 16h15m41s <==========End TIME IN WRITE

    Please check the time stamps which I have got, because of this I know that the hash is not be been deleted even though I write to the file and I am confused as to what is happening.

      Hi All, Thanks for looking at it..I figured out the problem, somehow the global hash always retained the past value. So, while reading I always initialized the hash key SCRIPT to null before building the hash. It worked for me perfectly now. Thank you.