LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-12-2006, 05:40 PM   #1
scuzzman
Senior Member
 
Registered: May 2004
Location: Hilliard, Ohio, USA
Distribution: Slackware, Kubuntu
Posts: 1,851

Rep: Reputation: 47
Using hash value as key for other hash in Perl


I'm having a fit with this. I have the following hashes set up:
Code:
my %fleet_def = ( # defenders fleet
  "sc" => Ship -> new(),
  "lc" => Ship -> new(),
  "lf" => Ship -> new(),
  "hf" => Ship -> new(),
  "cr" => Ship -> new(),
  "bs" => Ship -> new(),
  "cs" => Ship -> new(),
  "rc" => Ship -> new(),
  "ep" => Ship -> new(),
  "bm" => Ship -> new(),
  "ss" => Ship -> new(),
  "de" => Ship -> new(),
  "rip" => Ship -> new(),
  "ml" => Ship -> new(),
  "sl" => Ship -> new(),
  "hl" => Ship -> new(),
  "gc" => Ship -> new(),
  "ic" => Ship -> new(),
  "pc" => Ship -> new(),
  "ssd" => Ship -> new(),
  "lsd" => Ship -> new(),
);
my %rand_hash = ( # hash for random number gen. to determine ship
  "1" => "sc",
  "2" => "lc",
  "3" => "lf",
  "4" => "hf",
  "5" => "cr",
  "6" => "bs",
  "7" => "cs",
  "8" => "rc",
  "9" => "ep",
  "10" => "bm",
  "11" => "ss",
  "12" => "de",
  "13" => "rip",
  "14" => "ml",
  "15" => "sl",
  "16" => "hl",
  "17" => "gc",
  "18" => "ic",
  "19" => "pc",
  "20" => "ssd",
  "21" => "lsd",
);
What I want to do using these, is call a random number, and use it to call a variable in the Ship struct that is set up, like this:
Code:
$rand = ( int(rand(13)) + 1 );
until ( defined( $fleet_att{$rand_hash{$rand}} -> quantity ) { #test if ship exists
  $rand = ( int(rand(13)) + 1 ); #if not, reinitialize the variable with a new rand
}
But, for some reason, every time I execute this, I get these errors:
Code:
[scuzzy@slackdell /home/scuzzy/ogame/perlsim/PerlSim]$ ./PerlSim.pl
syntax error at ./PerlSim.pl line 464, near ") {"
syntax error at ./PerlSim.pl line 470, near ") {"
syntax error at ./PerlSim.pl line 475, near "}"
Execution of ./PerlSim.pl aborted due to compilation errors.
[scuzzy@slackdell /home/scuzzy/ogame/perlsim/PerlSim]$
And yes, I'm doing this multiple times (hence the similar errors). What I don't understand, is that ") {" never appears in the code, so I can't isolate the problem, and I have trouble believing Perl cannot do this. Just in case it's needed, here is the entire section of code in which these are used:
Code:
  foreach $ship ( keys %fleet_def ) {
    $rand = ( int(rand(13)) + 1 );
    until ( defined($fleet_att{$rand_hash{$rand}} -> quantity) { #test if ship exists
      $rand = ( int(rand(13)) + 1 ); #if not, reinitialize the variable with a new rand
    }
    &shoot($ship, $rand_hash{$rand}, 2); # call &shoot function
    while ( &rf($ship, $rand) ) { # call &rf function to see if ship shoots again
      $rand = ( int(rand(13)) + 1 );
      until ( defined( $fleet_att{$rand_hash{$rand}} -> quantity ) { #test if ship exists
        $rand = ( int(rand(13)) + 1 ); #if not, reinitialize the variable with a new rand
      }
      &shoot($ship, $rand_hash{$rand}, 2); # call &shoot function
    }
  }
 
Old 02-12-2006, 11:34 PM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,415

Rep: Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785
Actually, the 1st line of your last quoted code block is:

foreach $ship ( keys %fleet_def ) {

which includes ") {" as per the error msg you are getting ...
Hopefully you are using:

#!/usr/bin/perl -w

and

use strict;

at the top of your code ?
 
Old 02-13-2006, 12:16 PM   #3
scuzzman
Senior Member
 
Registered: May 2004
Location: Hilliard, Ohio, USA
Distribution: Slackware, Kubuntu
Posts: 1,851

Original Poster
Rep: Reputation: 47
OK - I got that problem solved - missed a parentheses

But I have other problems now. When I go to execute it, I get these errors:
Code:
[scuzzy@slackdell /home/scuzzy/ogame/perlsim/PerlSim]$ ./PerlSim.pl
Global symbol "$hull" requires explicit package name at ./PerlSim.pl line 139.
Global symbol "$weapon" requires explicit package name at ./PerlSim.pl line 140.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 140.
Global symbol "$hull" requires explicit package name at ./PerlSim.pl line 141.
Global symbol "$weapon" requires explicit package name at ./PerlSim.pl line 141.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 141.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 146.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 146.
Global symbol "$weapon" requires explicit package name at ./PerlSim.pl line 146.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 147.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 147.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 148.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 148.
Global symbol "$hull" requires explicit package name at ./PerlSim.pl line 150.
Global symbol "$hull" requires explicit package name at ./PerlSim.pl line 151.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 157.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 158.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 158.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 159.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 160.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 160.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 164.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 165.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 165.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 166.
Global symbol "$target" requires explicit package name at ./PerlSim.pl line 167.
Global symbol "$shield" requires explicit package name at ./PerlSim.pl line 167.
Global symbol "%rf_hash" requires explicit package name at ./PerlSim.pl line 221.
Global symbol "%rf_hash" requires explicit package name at ./PerlSim.pl line 222.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 446.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 449.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 450.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 451.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 452.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 453.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 454.
Global symbol "$desc" requires explicit package name at ./PerlSim.pl line 455.
Execution of ./PerlSim.pl aborted due to compilation errors.
[scuzzy@slackdell /home/scuzzy/ogame/perlsim/PerlSim]$
I think this might be a problem with the scoping, but there has to be a more elegant way of fixing that then explicitly saying $main:: on every variable. That said, the current code is here: http://www.scuzzman.org/perl/PerlSim.pl

Edit: I just made all the variables global, and now that's not happening... I shouldn't do this though, should I? http://www.scuzzman.org/perl/PerlSimv2.pl

Last edited by scuzzman; 02-13-2006 at 12:39 PM.
 
Old 02-13-2006, 05:54 PM   #4
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,415

Rep: Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785
A few pts; feel free to ignore ...

1. Perl is not shell ie you do not have to pre-declare all your fns before you use them. Try the C method ie after any global declarations (see below), start with a main or ctrl fn and physically put the other subs below that. Perl is sort-of compiled before it's run.

2. Try to only declare variables as 'my' within the sub they are used. Pass as params where needed.
My guideline is that if you need a var in a lot of subs, declare a 'global' pkg and put them in there eg:

<code>
# Declare Config pkg so we can refer to it anywhere
{
package cfg;

# Config file params
%cfg:arams = ();

# Database handle
$cfg::dbh = '';
}
</code>

3. Put a proper header for each sub, so you and/or anyone else can work out what's happening. here's an example of the way I do it:
<code>
#******************************************************************************
#
# Function : process_cc_rows
#
# Description : Main ctrl sub to delete cc rows older than eg 6 mths.
#
# Params : none
#
# Returns : none
#
#******************************************************************************
sub process_cc_rows
{
my (
$error_msg # log/email error if any
);

# Create a txn wrapper in case we have to rollback
db_start_txn();

# Delete all rows older than cfg specified
db_delete_cc_rows();
}
</code>

4. Personally, rather than require the user to re-enter all params each time, I'd create a (plain text) config or data file they can edit, so they can only change the values they want to (& change their minds easily).
Then just read the file at startup.

5. As you say, try not to use (unqualified) globals & try to minimise the num that you do you use. How different subs a var is used in constitute justification for putting a var into a global pkg is a personal judgement call. ;-)

6. No need to prefix subs with '&' when calling them. (unless passing as a ref ie \&sub_name). That's old-school Perl v4.

HTH
 
Old 02-13-2006, 05:56 PM   #5
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,415

Rep: Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785
PS : Note to moderators: why can't I edit my post??? I am logged in ...
 
Old 02-14-2006, 05:51 AM   #6
scuzzman
Senior Member
 
Registered: May 2004
Location: Hilliard, Ohio, USA
Distribution: Slackware, Kubuntu
Posts: 1,851

Original Poster
Rep: Reputation: 47
Thanks for the pointers - my little project is starting to come together now
I have yet to implement your suggestions (though, I likely will). I'm waiting until I at least get it to work right once... then, I'm going to worry about pretty code vs. functional code. One thing though, it is VERY slow - would making the variables local speed it up?
 
Old 02-14-2006, 06:08 PM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,415

Rep: Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785Reputation: 2785
No, speed is generally due to bad design at some level eg unnecessary loops, wrong algorithms or badly written algorithms.
As for 'pretty' vs 'working', as someone whose been doing this for xxxxx yrs, take it from me, if you don't make it look right as you go, you'll never have time/inclination to go back and correct it later, esp in commercial env.
Also, it makes it easier to debug as you go.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl and Hash automatic PB0711 Programming 3 09-23-2005 03:14 AM
Generating hash in perl ? MikeFoo1 Programming 3 05-21-2005 07:03 PM
Perl: hash tying amnesty_puppy Programming 1 01-18-2005 12:03 AM
Hash-sort like in PERL in C++ nyk Programming 4 06-11-2004 09:40 AM
Hash Key on keyboard changed functioin!? breakerfall Linux - General 1 01-11-2004 09:07 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration