local $\ = "\n"; local $/ = ''; open CODES, "> $code_file" or die "Couldn't open codefile: $!\n"; my $csv = Text::CSV->new; $csv->combine('code', 'desc'); print CODES $csv->string; my %hash = eval ; my @full_code_list = (); foreach my $key (keys %hash) { print "Looking at code [$key]...\n"; my @list = gen_codes($hash{$key}); push @full_code_list, @list if @list; } foreach my $aref (@full_code_list) { my ($code, $desc) = @$aref; $csv->combine($code, $desc); print CODES $csv->string; } sub gen_codes { my $href = shift; my $source = $href->{'source'}; my $base_desc = $href->{'desc'}; my @codes = (); my @element_hashes = @$href{@{$href->{'elements'}}}; my $code_str_sub = $href->{'code_str'}; my $desc_str_sub = $href->{'desc_str'}; my @code_args = ($source); my @desc_args = ($base_desc); sub getvalues { my ($elems, $codes, $c_sub, $d_sub, $code_args, $desc_args) = @_; my ($element, @remaining_elems) = @$elems; for my $code (keys %$element) { my $desc = $element->{$code}; my $c_args = [ @$code_args, $code ]; my $d_args = [ @$desc_args, $desc ]; if (@remaining_elems) { getvalues(\@remaining_elems, $codes, $c_sub, $d_sub, $c_args, $d_args); } else { push @$codes, [&$c_sub(@$c_args), &$d_sub(@$d_args)]; } } } getvalues(\@element_hashes, \@codes, $code_str_sub, $desc_str_sub, \@code_args, \@desc_args); return @codes; } __END__ my %hash = ( 'FI_SWP_PLAIN_VANILLA-SPREADS' => { source => 'FDER,SWAPSPRD', desc => 'Swaps - Plain Vanilla Spreads', elements => [qw/term attr/], term => { '2Y' => '2 Years', '3Y' => '3 Years', '4Y' => '4 Years', '5Y' => '5 Years', '6Y' => '6 Years', '7Y' => '7 Years', '8Y' => '8 Years', '9Y' => '9 Years', '10Y' => '10 Years', '12Y' => '12 Years', '15Y' => '15 Years', '20Y' => '20 Years', '25Y' => '25 Years', '30Y' => '30 Years', '40Y' => '40 Years' }, attr => { RT_MID => 'Mid Rate', RT_BID => 'Bid Rate', RT_OFF => 'Offer Rate', AM_MOD_DUR => 'Modified Duration', DT_VALUE => 'Value Date', DT_MATURITY => 'Maturity Date' }, code_str => sub { my ($s,$t,$a) = @_; return "DB($s,$t,$a)"; }, desc_str => sub { my ($d,$t,$a) = @_; return "$d: $t $a"; } } );