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

Hi Monk
sub DeleteValueTreeWithinHash { my $HashData = $_[0]; my $FindValue = $_[1]; my $value = &RecursiveFunctionToDeleteValueWithinHash($HashData, +$FindValue); print Dumper ($value); %{$HashData} = undef; %{$HashData} = %{$value}; print Dumper ($HashData); }
I have this function which is called by &DeleteValueTreeWithinHash(\%HashData, "index"); when I do a dumper on $value, i see all this data to screen. when I do a dumper on $HashData, i see no values.
$VAR1 = { '' => undef };
Any ideas on what i'm doing wrong? All I wanted to do was create a recursive function and delete a branch or element if it finds the text there. Update: Maybe I didn't put enough details so here is everything. This below is how %HashData looks like before this function line &DeleteValueTreeWithinHash(\%HashData, "index");
$VAR1 = { '0.29 type (ABC) {' => { '19.29 }' => {}, '18.28 ' => {}, '6.27 location(Y) {' => { '6.11 ' => {}, '7.12 + direction : out; ' => {}, '17.26 ' => {}, '18.27 + }' => {}, '8.13 + surface : 0.0; ' => {}, '10.25 + internal_power() {' => { + '16.24 ' => {}, + '11.17 related_outlet : "A"; ' => {}, + '12.23 rise_power(wind_template_7x +7) {' => { + + '14.21 index_2 ("4,5,6,7"); ' => {}, + + '13.20 index_1 ("1,2,3,4"); ' => {}, + + '15.22 hello : "kitty"; ' => {}, + + '12.19 ' => {}, + + '16.23 }' => {} + + }, + '10.16 ' => {}, + '17.25 }' => {} + }, '9.14 + function : "A"; ' => {} }, '2.8 location(A) {' => { '2.5 ' => {}, '4.7 + surface : 0.004189; ' => {}, '3.6 + direction : in; ' => {}, '5.8 } +' => {} }, '5.9 ' => {}, '1.3 area : 7.761600; ' => {}, '0.2 ' => {} }, '19.30 ' => {} };
This is my recursive function to remove the element. Note my hash structure above is multi dimensional such that it has no limit to it's depth.
sub RecursiveFunctionToDeleteValueWithinHash { my $HashData = $_[0]; my $FindValue = $_[1]; my $keys; foreach $keys (sort { $a <=> $b } keys %{$HashData}) { if ($keys =~ m/^(([\d]+)\.([\d]+) )/) { my $MarkerNumber = $1; my $line_data = $keys; $line_data =~ s/^([\d]+)\.([\d]+) //; if ($line_data =~ m/$FindValue/) { delete $$HashData{$keys}; next ; } my @values = (sort { $a <=> $b } keys %{$$HashData{$keys}}); if (scalar(@values) != 0) { $$HashData{$keys} = &RecursiveFunctionToDeleteValueWithinH +ash($$HashData{$keys}, $FindValue); } } } return $HashData; }
This is the value of print Dumper ($value); I just want to set this as my main hash. Notice that any values with the word index is removed from the hash?
$VAR1 = { '0.29 type (ABC) {' => { '19.29 }' => {}, '18.28 ' => {}, '6.27 location(Y) {' => { '6.11 ' => {}, '7.12 + direction : out; ' => {}, '17.26 ' => {}, '18.27 + }' => {}, '8.13 + surface : 0.0; ' => {}, '10.25 + internal_power() {' => { + '16.24 ' => {}, + '11.17 related_outlet : "A"; ' => {}, + '12.23 rise_power(wind_template_7x +7) {' => { + + '15.22 hello : "kitty"; ' => {}, + + '12.19 ' => {}, + + '16.23 }' => {} + + }, + '10.16 ' => {}, + '17.25 }' => {} + }, '9.14 + function : "A"; ' => {} }, '2.8 location(A) {' => { '2.5 ' => {}, '4.7 + surface : 0.004189; ' => {}, '3.6 + direction : in; ' => {}, '5.8 } +' => {} }, '5.9 ' => {}, '1.3 area : 7.761600; ' => {}, '0.2 ' => {} }, '19.30 ' => {} };

Replies are listed 'Best First'.
Re: Problems With Hash Pointer Assignments
by gaal (Parson) on Nov 30, 2004 at 20:32 UTC
    Several points.

    1. Perl references are not c pointers.

    2. What is RecursiveFunctionToDeleteValueWithinHash() (whew!) supposed to return? If it is a recursive functions to delete a value within the hash, why does it need to return a *value* at all? That is, shouldn't it just return success or failure?

    3. What do you want this code to do?
      %{$HashData} = undef; %{$HashData} = %{$value};
      You are deleting the data refered to by $HashData (and in an unidiomatic way: better to say %$HashData = () if you really want that -- but you don't), and are then populating it with a copy of whatever was (refered to) in $value. Why? If $value has the correct data, why doesn't DeleteValueTreeWithinHash() simply return it? Oh, you want an IN/OUT function? Fine, then why doesn't RecursiveFunctionToDeleteValueWithinHash() really do what it name claims and modify the data referenced by its argument?

    4. Is there a reason why you are using $_[0] and $_[1]? They *can* be used for a tricky way to get in/out function parameters, but that's not always a good idea, and when you're dealing with references anyway, there's hardly any need, anyway. Modify the referenced data; your called will see the changes.

    Do yourself a favor and read perlref (or perlreftut) carefully.

      1. I guess that was school. 2. I would have liked it to just delete the value. But I was having problems and just tried returning the hash ref of each branch. 3. I just wanted to assign the hash structure of value into hashdata so I can use the %HashData normally in the main program. I guess I can change the name. 4. Do you mean i should use shift?
          But I was having problems and just tried returning the hash ref of each branch.
        That's not going to prove very useful, because then in the caller you'd need to assemble the branches again. delete can handle indirection: You can do something like

        delete $node->{$doomed_key}; # recurse through remaining elements

          I just wanted to assign the hash structure of value into hashdata so I can use the %HashData normally in the main program.

        That's fair enough: but you don't need to muck around with copies to achieve that. If in the caller code you have %Hash, and call your function with an argument \%Hash, any changes made indirectly to that data will show up in the caller. This is one of the main features of references.

          Do you mean i should use shift?

        It's a matter of style, so there will be differing opinions, but generally you can use my ($arg1, $arg2, ...) = @_ to get your parameters. (Sometimes shift is more appropriate, and sometimes even $_[0] etc. are the Right Thing -- but not typically.)

Re: Problems With Hash Pointer Assignments
by dragonchild (Archbishop) on Nov 30, 2004 at 20:21 UTC
    Why are you doing
    %{$HashData} = undef; %{$HashData} = %{$value};
    That's not very standard Perl. However, I have no idea what to suggest to you until you explain some more about what you're trying to do ...

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Problems With Hash Pointer Assignments
by osunderdog (Deacon) on Nov 30, 2004 at 20:14 UTC

    Missing a lot of details, some example input and output would be appreciated. But at a glance, are you sure that $value is a hash reference?

    Oh, if this is a recursive function, and you are depending on the return result (rather than manipulation of the reference) then you need to return something from the recursive function. Is RecursiveFunctionToDeleteValueWithinHash really supposed to be DeleteValueTreeWithinHash?

    Update. Added some more thoughts.


    "Look, Shiny Things!" is not a better business strategy than compatibility and reuse.


    OSUnderdog
Re: Problems With Hash Pointer Assignments
by revdiablo (Prior) on Nov 30, 2004 at 20:23 UTC

    As osunderdog says, there is a lot of important detail missing from your question. To give any sort of meaningful answer, we probably need to see:

    • The code for RecursiveFunctionToDeleteValueWithinHash (I would urge you to consider a shorter name. This is, frankly, terrible.)
    • The hash you're passing to DeleteValueTreeWithinHash (This name isn't as bad as the other, but still could be shortened considerably.)
    • The line where you call DeleteValueTreeWithinHash, so we can see how you pass in the hash.
Re: Problems With Hash Pointer Assignments
by NetWallah (Canon) on Nov 30, 2004 at 20:25 UTC
    It works fine for me ( perl, v5.8.3 built for MSWin32-x86-multi-thread):
    >perl -MData::Dumper -we "my $v={''=>undef}; my $h; %$h=%$v; print Dum +per $h" --OUTPUT-- $VAR1 = { '' => undef };
    The code "%{$HashData} = undef;" is incorrect, and not doing anything anyway.

        ...each is assigned his own private delusion but he cannot see the baggage on his own back.