Inspired by this answer and previous a commentator of code review use:
Given a complex Perl data structure, traverse/jigger/modify as follows:
- If
ORACLE_SID
is 'key' in any hash then keep onlyORACLE_SID
section matching of$ENV{ORACLE_SID}
- Eliminate any single level arrays, if after step 1, we're left with
s_level
arrays - Enhance values of simple content values based on requirement
What else or better way can be done to achieve the intended goal?
# $reduce_1level is set by the caller of jigger()
our $reduce_1level = 1;
sub jigger
{
our $cds; local *cds = \shift;
my $type = ref $cds or return;
if ($type eq 'HASH') {
foreach my $key (keys %$cds) {
if (ref $cds->{$key}) {
$cds->{$key} = reduce_by_oracle_sid ($cds->{$key});
delete $cds->{$key} if not defined $cds->{$key};
jigger ($cds->{$key}) if ref $cds->{$key};
}
else {
$cds->{$key} = enhance_value ($cds->{$key});
}
}
}
elsif ($type eq 'ARRAY')
{
@$cds = grep { $_ = reduce_by_oracle_sid($_); defined } @$cds;
foreach my $elem (@$cds) {
if (ref $elem) {
jigger ($elem);
}
else {
$elem = enhance_value ($elem);
}
}
$cds = $cds->[0] if @$cds == 1 and $reduce_1level;
}
}
I'm really only after jigger()
. I'm listing the helper subs for the the same price.
sub reduce_by_oracle_sid
{
my $node = shift;
return $node unless ref $node eq 'HASH' and exists $node->{ORACLE_SID};
return unless $node->{ORACLE_SID} =~ /$ENV{ORACLE_SID}/;
delete $node->{ORACLE_SID};
# If there was was just 'value' then we return only value...
return exists $node->{value} ? $node->{value} : $node;
}
sub enhance_value
{
my $v = shift;
# Take out double //'s
$v =~ s{//}{}g;
# trim whitesapce
$v =~ s/^\w*(\W*)\w*$/$1/;
# inject SQL commands ...
#
# ... n more ...
return $v;
}