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

Hi Monks!

I am trying to access this hash and I cant understand why I am getting this error:
Global symbol "$my_data_ref" requires explicit package name ....
Can someone let me know how I should have this done?
Thanks for the Help!
... # Create a hash with the data my %my_data = ( names => $some_data); my $my_data_ref = \%my_data; my @all_names = split/\n/, ${ $my_data_ref } { names }; foreach my $rows (@all_names){ print $rows."\n"; } ...

Replies are listed 'Best First'.
Re: Hash Ref Error
by stevieb (Canon) on Sep 15, 2015 at 21:27 UTC
    Untested (I'm on my phone): $my_data_ref->{names};

    I'll test and explain if nobody else does shortly.

    Update: There's nothing technically wrong with your code, and it should work (as the Monks who tested it below can show). However, it isn't the most idiomatic Perl out there. Right off the bat, although perl allows whitespace nearly anywhere, it's clearer if you keep your delimiters together: ${ $my_data_ref }{ names }

    What this does:

    ${ $my_data_ref } { names }

    is it dereferences $my_data_ref hash reference, and converts (actually it forces) the value(s) of its names key into a scalar value. It is equivalent to the more idiomatic:

    my $scalar = $my_data_ref->{names}

    Both do the same thing, but one is a bit more understandable at-a-glance, so long as the left-hand side (or within another line or two) makes it clear what type (scalar or list) you're pulling out.

    -stevieb

      I would do this way:
      # Create a reference to an anonymous hash with the data my $my_data = { names => $some_data }; #my $my_data_ref = \%my_data; my @all_names = split/\n/, ${ $my_data } { names }; foreach my $rows (@all_names){ print $rows."\n"; } ...

        Excellent Maresia! Here's a couple of different ways you can do it. Note that double-quotes automatically 'interpolate' variables (ie. expands variables to their values), so you can even do "$rows\n"; instead of $rows."\n" :)

        my %my_data = ( names => $some_data); my $my_data_ref = \%my_data; my @all_names = split /\n/, $my_data_ref->{names}; for (@all_names){ print "$_\n"; } # or even skip creating the @all_names array altogether print "$_\n" for split /\n/, $my_data_ref->{names};

        I wouldn't recommend the latter unless you're really just doing something with the extracted information immediately on the spot.

Re: Hash Ref Error
by BillKSmith (Monsignor) on Sep 16, 2015 at 02:50 UTC
    The error message is telling you that $my_data_ref is not declared even though it clearly is. I suspect that there is an error earlier in the program, perhaps a missing quote or semicolon. It is also possible that $my_data_ref is used somewhere else (where it is out of scope). The line number in the error message is important. Are you sure that it refers to line that you posted?
    Bill
Re: Hash Ref Error
by tangent (Parson) on Sep 15, 2015 at 21:41 UTC
    Your code works fine for me - what version of perl are you using?

      The OPed code should work fine with any Perl version:

      c:\@Work\Perl>perl -wMstrict -MData::Dump -le "print qq{perl version: $] \n}; ;; my %my_data = (names => 'AbCdEfGh', states => 'FooBarBaz'); my $my_data_ref = \%my_data; ;; my @all_names = split /(?=[[:upper:]])/, ${ $my_data_ref } { names }; dd \@all_names; ;; my @ra = split /(?=[[:upper:]])/, $my_data_ref->{states}; dd \@ra; " perl version: 5.008009 ["Ab", "Cd", "Ef", "Gh"] ["Foo", "Bar", "Baz"]
      (5.8 is the earliest I can test.)


      Give a man a fish:  <%-{-{-{-<

        After assuming that $some_data is a single string with newlines, I can also confirm it works on v5.8, v5.18 and v5.22.