Je55eah has asked for the wisdom of the Perl Monks concerning the following question:

*HASH(0x37fc4)$

That is the unexpected result that I gaet from the following code. Why is it making a hash? What I really want is a big string that is formatted as a easy to read list. Thank you,

# Begin %admin_expenses = { 'President' => 60000, 'Vice President' => 50000, 'Engineer' => 50000, 'House Keeper' => 50000, '6 Part Time Attendants' => 120000, '12 Interns' => 12000, 'Contractor' => 50000, 'Hired Professionals' => 60000, 'Lawyers' => 60000, 'Law Student' => 40000, 'Nurse' => 60000, 'Facility + Utilities' => 40000, 'Truck' => 40000, 'Forklift' => 20000, 'Driver / Contractor' => 70000, 'Phone Attendant' => 30000, 'pallets, packaging, and office supplies' => 60000 }; while(($expense, $amount) = each %admin_expenses) { $total_admin_expenses = $total_admin_expenses + $amount; $adminExpenses .= '*' . $expense . '$' . add_commas($amount) . "\n +"; } $ $adminExpenses = "###Admin Expenses = \n" . $adminExpenses; print $adminExpenses; sub add_commas { my $number = reverse $_[0]; $number =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g; return scalar reverse $number; } # End

Replies are listed 'Best First'.
Re: Please help me print this hash.
by frozenwithjoy (Priest) on Jun 19, 2012 at 00:38 UTC
    These are two of the most important things you can do (besides reading up on hashes and references, etc.) to fix your script:
    • use warnings;
    • use strict;

    When I ran your script with use warnings;:

    Reference found where even-sized list expected at ./junk.pl line 6. Use of uninitialized value $amount in addition (+) at ./junk.pl line 2 +7. Use of uninitialized value $total_admin_expenses in addition (+) at ./ +junk.pl line 27. Use of uninitialized value $_[0] in reverse at ./junk.pl line 35.

      It appears to me that the best solution is to declare the variables with our. Is there any way to do this without writing our for each variable or without listing all of the variable names within an our declaration and again when I assign values to them?

      Since I am only writing a report with Perl, I don't have a lot of stuff competing for the namespace. I would like to keep the readability high and the amount of redundancy low so that the code is easy to change and easy to read. If I package this into an object with getters and setter later then I can find and replace our with my, but for now I think that our seems to be the best choice. Thoughts?

      use strict; # while I would like to do this: # # our # ( # $x = 1; # $y = 2; # ); # # it seems that I must do: use ($x, $y); $x = 1; $y = 2; # or this: our $x = 3; our $y = 4; # before I can do: $x = 5; $y = 6;

      should I do the following instead?

      use strict; no strict "vars"; $x = 5; $y = 6;

      Thank you,

        With very short scripts (less than 6 lines, say), it probably confers no benefits.

        For anything longer, use strict qw(subs vars) seems to always be appropriate. use strict qw(refs) is usually appropriate, but it's sometimes useful to allow non-strict refs.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        Is there any way to set my as the default scope for variables when no scope is specified? Why isn't this the case now?

        Thanks,
Re: Please help me print this hash.
by Anonymous Monk on Jun 19, 2012 at 00:11 UTC
Re: Please help me print this hash.
by Je55eah (Novice) on Jun 19, 2012 at 01:05 UTC
    Those were both excellent tips. Thank you,
Re: Please help me print this hash.
by johngg (Canon) on Jun 19, 2012 at 10:03 UTC

    Here's another way to comma'ify your numbers that avoids the two reversees by using substr, pos and look-around assertions in the regex.

    knoppix@Microknoppix:~$ perl -E ' > sub add_commas > { > my $number = shift; > substr $number, pos $number, 0, q{,} > while $number =~ m{ (?<= \d ) (?= \d{3} (?: , | \z ) ) }xg; > return $number; > } > > say add_commas( $_ ) for qw{ > 1 > 12 > 123 > 1234 > 12345 > 123456 > 1234567 > 12345678 > 123456789 > 1234567890 > };' 1 12 123 1,234 12,345 123,456 1,234,567 12,345,678 123,456,789 1,234,567,890 knoppix@Microknoppix:~$

    I hope this is of interest.

    Cheers,

    JohnGG