2

I have built a loop that finds all of the VMDKs for a perticular VM and then create a hash of the output, then it tests whether the disk is actually present by looking for a parameter in the VMX file. Then if the disk is not present it deletes it from the hash. The problem I running into is how to delete a hash key that has no disks defined.

Here is the code block;

    while ($vmx_file =~ m/^(ide(?<PORT>[0-1])\:(?<DISK>[0-1]))\.present\s+=\s+"(?<PRESENT>[^"]+)["]/xmg) {
        $ide_port = "$+{PORT}";
        $ide_disk = "$+{DISK}";
        $present = "$+{PRESENT}";
        if ($present eq 'FALSE') {
            delete $virtual_disks{$vm}{"IDE$ide_port"}{"Disk$ide_disk"}
        }
    } 

This is what I am getting as a hash when the above statement is true and it deletes the missing disks.

$VAR1 = {
      'Test01' => {
                    'SCSI0' => {
                                 'Disk0' => '/vmfs/volumes/4c8fd27b-5876fc36-80f4-0015179fd63c/Test01/Test01.vmdk',
                                 'Type' => 'lsilogic',
                                 'Disk1' => '/vmfs/volumes/4c8fd27b-5876fc36-80f4-0015179fd63c/Test01/Test01_1.vmdk'
                               },
                    'IDE1' => {
                                'Disk0' => '/vmfs/volumes/4c8fd27b-5876fc36-80f4-0015179fd63c/ubuntu-10.10-desktop-i386.iso'
                              },
                    'IDE0' => {}
                  }

As you can see the sub hash 'IDE0" is empty, because the disk that was listed was not present in the VMX file. Now what I would like to do is remove the entire 'IDE0' hash because there is nothing in it. But I only want it to delete it if it hash nothing. becasue it can have up to 2 disks in it as per IDE specs. Follow me?

AtomicPorkchop
  • 2,625
  • 5
  • 36
  • 55
  • I'm having difficulty understanding the circumstance you're trying to deal with. Normally, Perl questions get answers quickly, so this is either harder to answer or harder to understand than usual - I think it is the latter. Did you experiment? I'm trying to understand what you might have in the data structure that you are looking to delete, and I'm failing to understand what might be in your hash of hashes. Your main code block shows a hash of hashes of hashes. You might be looking for `defined`, but there usually isn't a need to delete something if it isn't defined. – Jonathan Leffler Jan 15 '11 at 20:50
  • Sorry for my broken thoughts let me update my question to be more clear on my needs. – AtomicPorkchop Jan 15 '11 at 20:54

1 Answers1

3

Count the remaining keys after your first round of deletion. If the count is zero, delete at the higher level.

 if (scalar keys %{ $virtual_disk{$vm}{"IDE$ide_port"} } == 0) {
      delete $virtual_disks{$vm}{"IDE$ide_port"}
        }
Narveson
  • 1,091
  • 1
  • 9
  • 15
  • I had to make a few slight modification to you solution but the idea work absolutely perfect. I needed the IF statement to look one more level down in the hash. Thanks for the help. – AtomicPorkchop Jan 15 '11 at 21:11
  • 1
    You don't need the "scalar" here. The == operator imposes scalar context on both sides. – Sean Jan 15 '11 at 21:45
  • 1
    But the `scalar` makes the intention of the code clearer. If only more programmers would do so many unnecessary things ... – mob Jan 16 '11 at 00:42
  • To me, the "scalar" makes the code less clear. It sends me off looking for a list context that isn't present. – Sean Jan 16 '11 at 06:23