Recurse on complex Perl data structure, applying needed rules
Is there an obvious reason why you don't use a cross-sectional Path tracer?

For instance, with Data::Dpath, seems like it could do what you want without too much fuss.

Your complicated example is quite trivial to extract nodes by ORACLE_ID at arbitrary depths.

use strict;
use warnings;

use Data::DPath qw( dpath );
use Data::Dump qw( pp );

$ENV{ORACLE_SID} = 6;

my $struct = {
  a =&gt; {
    b =&gt; {
      c =&gt; {
        x =&gt; {
          y =&gt; {
            name       =&gt; "In Hash",
            ORACLE_SID =&gt; $ENV{ORACLE_SID}
          },
          z =&gt; {
            name       =&gt; "Non Target",
            ORACLE_SID =&gt; 5,
          }
        },
        aa =&gt; [ { ORACLE_SID =&gt; $ENV{ORACLE_SID}, name =&gt; "In Array" } ],    # just to make things interesting
      }
    },
  },
};

# find all nodes no matter how deep that have a child, which, themselves
# contains a hash with a key "ORACLE_SID"

my (@oracles) = dpath( '//ORACLE_SID[value eq ' . $ENV{ORACLE_SID} . ']/..' )-&gt;match($struct);
pp(@oracles);

#(
#  { name =&gt; "In Hash", ORACLE_SID =&gt; 6 },
#  { name =&gt; "In Array", ORACLE_SID =&gt; 6 },
#)


That at very least, makes the most of your logic extraneous, and the essentials of "what data are you querying" and "What are you doing with that data" become more clear to the code reader.