use Algorithm::Loops qw( NestedLoops ); sub get_target_iter { my ($envs) = @_; my $iter = NestedLoops( [ [ keys %$envs ] , sub { [ keys %{$envs->{$_[0]} } ] }, sub { [ keys %{$envs->{$_[0]}{$_[1]} } ] }, sub { [ keys %{$envs->{$_[0]}{$_[1]}{$_[2]}} ] }, ], ); return sub { if (my ( $env_name, $platform_name, $host_name, $target_name, ) = $iter->()) { my $target = $envs->{$env_name } {$platform_name} {$host_name } {$target_name }; my $total_capacity = $target->{total_capacity}; my $free_capacity = $target->{free_capacity}; return $env_name, $platform_name, $host_name, $target_name, $total_capacity, $free_capacity; } return; }; }