go ahead... be a heretic PerlMonks

### Getting a hash from a file

by jedikaiti (Friar)
 on Mar 23, 2010 at 23:51 UTC Need Help??
jedikaiti has asked for the wisdom of the Perl Monks concerning the following question:

I asked this in CB yesterday, but need further input... I have a hash in a file. Literally, the file is a few lines of comments followed by...

%Verbs = ( "arm" => { description => " A prerequisite command for a potentially hazar +dous command. ", discrete => 1, }, "close" => { description => " Mechanically close a device controlled by the +command element. \\emph{close} works in conjunction w +ith the \\emph{open} verb. ", discrete => 1, }, "disable" => { description => " Deactivate a capability or function. \\emph{d +isable} works in conjunction with the \\emph{enable} v +erb. ", discrete => 1, }, "dump" => { description => " Copy a specific data buffer of the command ele +ment to telemetry. ", discrete => 0, }, "enable" => { description => " Activate a capability or function. \\emph{ena +ble} works in conjunction with the \\emph{disable} +verb. ", discrete => 1, }, );

All I want to do is call this somehow from my perl script, so that I can use the hash. I have no control over the creation of this file.

bart made the suggestion "Then look at do and require (and eval and use to get the whole picture)", which I did. I looked them up on perldoc.perl.org, and I'm not sure if they don't do what I want them to do, or if I'm just using them wrong. For example:

#!/usr/bin/perl -w use strict; use Template; do 'cmd_verbs_test.pm'; print ("Hello!\n"); #do 'cmd_verbs_test.pm'; # opens file with Verbs hash foreach my $cmd (sort keys %Verbs){ # sets value to description text without preceeding or ending newl +ines and spaces my$desc = $Verbs{$cmd}{description}; print("Command: $cmd \n"); print("Description:$desc \n"); print("Discrete: $Verbs{$cmd}{discrete} \n\n"); } print("Done!\n");

When I try to run this, it tells me Global symbol "%Verbs" requires explicit package name at test3.pl line 11. And on lines 13 and 17.

I have also read through Reading Variables from a File and Object Serialization Basics. From reading those, I'm thinking I will need to use one of the modules listed to do what I want to do.

I do, however, want to keep this as simple as possible, and thought I'd ask here to make sure I'm not just doing something wrong with how I'm using do, or if there's another way.

Thanks, Monks!
Kaiti

Replies are listed 'Best First'.
Re: Getting a hash from a file
by BrowserUk (Pope) on Mar 24, 2010 at 01:35 UTC

You're being bitten by scoping. Try it this way.

C:\test>type fileWithHash.pl ( fred=>1, bill=>2, Joe=>3, jack=>4 ); C:\test>perl -MData::Dump=pp -Mstrict -wle"my %hash = do 'fileWithHash.pl'; pp\%hash" { Joe => 3, bill => 2, fred => 1, jack => 4 }

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Getting a hash from a file
by toolic (Bishop) on Mar 24, 2010 at 00:39 UTC
I shortened your .pm file to look like this (just as a test case):
%Verbs = (a=>1, b=>2);
Then your main script would look like:
use strict; use warnings; use Data::Dumper; my %Verbs = do 'cmd_verbs_test.pm'; print Dumper(\%Verbs); __END__ $VAR1 = { 'a' => 1, 'b' => 2 }; See also: Re: Calling a Variable from another file Re: Getting a hash from a file by kikuchiyo (Monk) on Mar 24, 2010 at 10:39 UTC An alternative method would be slurping the file into a string and then eval'ing the string. This way you'd have the resulting hash in the same lexical scope as the rest of your variables (or more precisely, the scope of the "imported" variable will be determined by the place of the declaration, see below). This method also allows you to "import" more than one variable from the file. Example: ############# # settings.pl %hash1 = ( a => 1, b => 2, ); %hash2 = ( c => 3, d => 4, ); ############# ############# # main.pl #!/usr/bin/perl -w use strict; use Data::Dumper; my %hash1; # declaring them here my %hash2; { local$/; open(my $fh, '<', 'settings.pl') || die "Can't open settings\n"; my$string = <$fh>; eval$string; close $fh; } print Dumper \%hash1; print Dumper \%hash2; ############# shell$ perl main.pl $VAR1 = { 'a' => 1, 'b' => 2 };$VAR1 = { 'c' => 3, 'd' => 4 };
Re: Getting a hash from a file
by itsscott (Sexton) on Mar 24, 2010 at 00:01 UTC
The way I have always done it and it worked for me fine was to do the following
require "filewithhash.pl";
Hope that helps.
I just tried it, and it returns the exact same error(s).
You can not use the .pm as an extension change it to .pl or .cfg or something else and I am sure you will find the error goes away. I am sure this one bit me many moons ago.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://830419]
Approved by planetscape
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2016-10-26 01:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How many different varieties (color, size, etc) of socks do you have in your sock drawer?

Results (330 votes). Check out past polls.