Q:

Manipulate and access the contents of a hash of hashes

I am having trouble with writing a Perl script.
This is the task:

My code works fine but has two issues. 

I want to add an element to the hash %grocery, which contains category, brand and price. When adding the item, first the system will ask for the category.
If the category does not exist then it will add a new category, brand and price from the user, but if the category already exists then it will take the brand name and price from the user and append it to the existing category.
When I try to do so it erases the preexisting items. I want the previous items appended with the newly added item.
This issue is with the max value. To find the maximum price in the given hash. I am getting garbage value for that.
What am I doing wrong?

Here is my full code:
use strict;
use warnings;

use List::Util qw(max);
use feature "switch";

my $b;
my $c;
my $p;
my $highest;

print "____________________________STORE THE ITEM_____________________\n";

my %grocery = (
    "soap"      => { "lux"   => 13.00, "enriche" => 11.00 },
    "detergent" => { "surf"  => 18.00 },
    "cleaner"   => { "domex" => 75.00 }
);

foreach my $c ( keys %grocery ) {
    print "\n";
    print "$c\n";
    foreach my $b ( keys %{ $grocery{$c} } ) {
        print "$b:$grocery{$c}{$b}\n";
    }
}

my $ch;

do {
    print "________________MENU_________________\n";
    print "1.ADD ITEM\n";
    print "2.SEARCH\n";
    print "3.DISPLAY\n";
    print "4.FIND THE MAX PRICE\n";
    print "5.EXIT\n";
    print "enter your choice \n";
    $ch = <STDIN>;
    chomp( $ch );

    given ( $ch ) {

        when ( 1 ) {
            print "Enter the category you want to add";
            $c = <STDIN>;
            chomp( $c );

            if ( exists( $grocery{$c} ) ) {

                print "Enter brand\n";
                $b = <STDIN>;
                chomp( $b );

                print "Enter price\n";
                $p = <STDIN>;
                chomp( $p );

                $grocery{$c} = { $b, $p };

                print "\n";
            }
            else {

                print "Enter brand\n";
                $b = <STDIN>;
                chomp( $b );

                print "Enter price\n";
                $p = <STDIN>;
                chomp( $p );

                $grocery{$c} = { $b, $p };

                print "\n";
            }
        }

        when ( 2 ) {

            print "Enter the item that you want to search\n";
            $c = <STDIN>;
            chomp( $c );

            if ( exists( $grocery{$c} ) ) {

                print "category $c exists\n\n";
                print "Enter brand\n";
                $b = <STDIN>;
                chomp( $b );

                if ( exists( $grocery{$c}{$b} ) ) {
                    print "brand $b of category $c exists\n\n";
                    print "-----$c-----\n";
                    print "$b: $grocery{$c}{$b}\n";
                }
                else {
                    print "brand $b does not exists\n";
                }
            }
            else {
                print "category $c does not exists\n";
            }
        }

        when ( 3 ) {

            foreach $c ( keys %grocery ) {

                print "$c:\n";

                foreach $b ( keys %{ $grocery{$c} } ) {
                    print "$b:$grocery{$c}{$b}\n";
                }
            }
        }

        when ( 4 ) {

            print "\n________________PRINT HIGHEST PRICED PRODUCT____________________\n";
            $highest = max values %grocery;
            print "$highest\n";
        }
    }

} while ( $ch != 5 );

A:

When I try to do so it erases the preexisting items. I want the previous items appended with the newly added item.

In this line you are overwriting the value of $grocery{$c} with a new hash reference.

$grocery{$c}={$b,$p};

Instead, you need to edit the existing hash reference.
$grocery{$c}->{$b} = $p;

That will add a new key $b to the existing data structure inside of $grocery{$b} and assign it the value of $p.
Let's take a look at what that means. I've added this to the code after %grocery gets initialized.
use Data::Dumper;
print Dumper \%grocery;

We will get the following output. Hashes are not sorted, so the order might be different for you.
 $VAR1 = {
      'cleaner' => {
                     'domex' => '75'
                   },
      'detergent' => {
                       'surf' => '18'
                     },
      'soap' => {
                  'enriche' => '11',
                  'lux' => '13'
                }
    };

As you can see we have hashes inside of hashes. In Perl, references are used to construct a multi level data structure. You can see that from the curly braces {} in the output. The very first one after $VAR1 is because I passed a reference of $grocery to Dumper by adding the backslash \ in front.
So behind the value for $grocery{"cleaner"} is a hash reference { "domex" => 75 }. To reach into that hash reference, you need to use the dereferencing operator ->. You can then put a new key into that hash ref like I showed above.
#                  ##!!!!!!!!!!
$grocery{"cleaner"}->{"foobar"} = 30;

I've marked the relevant parts above with a comment. You can read up on this stuff in these documents: perlreftut, perllol, perldsc and perlref.

This issue is with the max value. To find the max of the values of the given hash. I am getting garbage value for that.

This problem is also based on the fact that you don't yet understand references.

 $highest = max values %grocery;

Your code will only take the values directly inside %grocery. If you scroll up and look at the Dumper output again, you'll see that there are three hash references inside of %grocery. Now if you do not dereference them, you just get their scalar representation. A scalar in Perl is a single value, like a number or a string. But for references it is their type and address. What looks like garbage is in fact the memory address of the three hash references in %grocery which has the highest number.
Of course that's not what you want. You need to iterate both levels of your data structure, collect all values and then find the highest one.
my @all_prices;
foreach my $category (keys %grocery) {
    push @all_prices, values %{ $grocery{$category} };
}
$highest = max @all_prices;
print "$highest\n";

I chose a very verbose approach to do that. It iterates over all categories in %grocery and then grabs all the values of the hash reference stored behind each of them. Those get added to an array, and in the end we can take the max of all of them from the array.

