Question about hashes of hashes

D

djacober

Hi all

I tried to pass a hash of hashes as a reference to a subroutine but
everytime I try to make an operation with to the hash I get the
following mistake. I found a lot of information on the web but it's
still not clear to me what I can do about it

Here's the error message I get:

djacober@tux ~/perl $ perl -w detect_eyes.pl > eyes.out
Can't use string ("1") as a HASH ref while "strict refs" in use at
detect_eyes.pl line 126.

Here's a the snippet of my code that causes the headache:

sub detect_eye {

my $ref_color = @_;
foreach my $line (@board_number) {
VALUE: foreach my $alpha (@board_alpha) {

## this line doesn't work !!!!
126: print "$line,$alpha : $ref_color->{$line}{$alpha} \n";


Here's how I call the subroutine:

sub main {
read_board();
detect_eye(\%white);
}


Can any one help?

Thanks for your support
Daniel
 
G

Gunnar Hjalmarsson

djacober said:
djacober@tux ~/perl $ perl -w detect_eyes.pl > eyes.out
Can't use string ("1") as a HASH ref while "strict refs" in use at
detect_eyes.pl line 126.

Can any one help?

If you make it easy to help, I'm sure someone can.

Please post a short but _complete_ program that people can copy and run
and that exhibits the problem you're having!
 
D

djacober

Gunnar said:
If you make it easy to help, I'm sure someone can.

Please post a short but _complete_ program that people can copy and run
and that exhibits the problem you're having!

Sorry I didn't want to overload with code:

Here's the complete code

Regards Daniel

#!/usr/bin/perl
#
#################################################################################
#
# detect_eyes.pl : perl program to find the double eyes in a go game
#
# Filename : detect_eyes.pl
#
# Version : 1.0
#
# Author : D. Jacober, DSAI 2001 8. Semester KI
# Date : 05.07.2005
# Changes :
#
# Input : Text file on the command line with a go board
# Output : Displays double eyes on the go board
#
#################################################################################

use strict;
use warnings;
use Time::localtime;
use IO::Handle;
###use Sort::Fields;

# Variablen deklarieren
my $infile = shift || "example.txt";
my $outfile = shift || "double_eyes.txt";
my %board = ();
my %white = ();
my %black = ();
my %empty = ();
my @open = ();
my @closed = ();
my @current = ();
my @board_number = (1,2,3,4,5);
my @board_alpha = ("A","B","C","D","E");
my $max_num = 5;
my $min_alpha = "A";
my $max_alpha = "F";

#################################################################################
# sub to read input file
#################################################################################

sub has_neighbour {
my ($line,$alpha) = @_;
my $value = $white{$line}{$alpha};
my $next_alpha=chr(ord($alpha)+1);
my $before_alpha=chr(ord($alpha)-1);
my $has_neighbour = 0;
my @new_member = ();

LINE: foreach my $num ($line-1,$line,$line+1) {
next LINE if ( ($num < 1) || ($num > $max_num) );

ALPHA: foreach my $char ($before_alpha,$alpha,$next_alpha) {
next ALPHA if ( ($num == $line) && ($alpha eq $char) );
next ALPHA if ( ($char lt $min_alpha) || ($char gt $max_alpha) );

if ( exists($white{$num}{$char}) && $value eq $white{$num}{$char}) {

foreach my $in_open (@open) {
next LINE if ("$num $char" eq $in_open);
}

foreach my $in_current (@current) {
next LINE if ("$num $char" eq $in_current);
}

print "inserting $num $char in open\n";
$new_member[$has_neighbour++] = "$num $char";
}

}
}

push(@new_member, @open);
@open = @new_member;
return $has_neighbour;
}

sub read_board {
my @alpha_coordinate;

open(INFILE,$infile) or die " cannot open $infile ";

while(<INFILE>) {
s/^\s//g;
chomp;
if (s/^\///) {
s/^\s//g;
@alpha_coordinate = split(/ /);
} elsif (s/^(\d+)//) {
my $line_no = $1;
s/^\s//g;
my @line = split / /;
my $n = 0;
foreach my $field (@line) {

#full board with all figures
$board{$line_no}{$alpha_coordinate[$n]} = $field;

#separate hashes for each color type (black, white and empty)
if ($field =~ /0/) {
$white{$line_no}{$alpha_coordinate[$n]} = $field;
} elsif ($field =~ /X/) {
$black{$line_no}{$alpha_coordinate[$n]} = $field;
} else {
$empty{$line_no}{$alpha_coordinate[$n]} = $field;
}

$n++;
}
} else { die "wrong input line \n"; }
}
close(INFILE);

}

sub detect_eye {

my $ref_color = @_;
foreach my $line (@board_number) {
VALUE: foreach my $alpha (@board_alpha) {
print "$line,$alpha : $ref_color->{$line}{$alpha} \n";

if (exists($white{$line}{$alpha}) ) {

if (has_neighbour($line,$alpha) > 1) {unshift(@current, "$line
$alpha");}

while ( $#open != -1 ) {
print "@open \n";
print "@current \n";
my ($num, $char) = split(/ /,shift(@open));

if (has_neighbour($num,$char) ) {unshift(@current, "$num
$char");}

}
exit;
}

}
}
}

sub main {
read_board();
detect_eye(\%white);
}

main();
 
D

djacober

Sven-Thorsten Fahrbach said:
Hi all

I tried to pass a hash of hashes as a reference to a subroutine but
everytime I try to make an operation with to the hash I get the
following mistake. I found a lot of information on the web but it's
still not clear to me what I can do about it

Here's the error message I get:

djacober@tux ~/perl $ perl -w detect_eyes.pl > eyes.out
Can't use string ("1") as a HASH ref while "strict refs" in use at
detect_eyes.pl line 126.

Here's a the snippet of my code that causes the headache:

sub detect_eye {

my $ref_color = @_;


Wrong context. This doesn't mean 'give me the first element of @_' (which is what you probably had in mind) but 'give me the number of elements in the list'. You pass the hashref \%white to the sub, so @_ contains one element, i.e. 1 is being assigned to $ref_color, hence the error message 'Can't use string ("1")...'. What you want to do is either:
1 - The C way : my $ref_color = $_[0]; or
2 - The Perl way: my $ref_color = shift;
shift() operates on @_ if no additional arguments are given and you should use it instead of accessing individual array elements by their subscripts, which is slower.
perldsc is also a good reference if you run into trouble with hashes of hashes or other data structures.

Yes you're a Genious so simple but took me some hours of my life seeking
in the docs

Thanks a lot

Regards Daniel
 
G

Gunnar Hjalmarsson

Sven-Thorsten Fahrbach said:
djacober said:
sub detect_eye {

my $ref_color = @_;

What you want to do is either:
1 - The C way : my $ref_color = $_[0]; or
2 - The Perl way: my $ref_color = shift;

or

3 - Another Perl way: my ($ref_color) = @_;

TIMTOWDI
 
S

Sven-Thorsten Fahrbach

Hi all

I tried to pass a hash of hashes as a reference to a subroutine but
everytime I try to make an operation with to the hash I get the
following mistake. I found a lot of information on the web but it's
still not clear to me what I can do about it

Here's the error message I get:

djacober@tux ~/perl $ perl -w detect_eyes.pl > eyes.out
Can't use string ("1") as a HASH ref while "strict refs" in use at
detect_eyes.pl line 126.

Here's a the snippet of my code that causes the headache:

sub detect_eye {

my $ref_color = @_;

Wrong context. This doesn't mean 'give me the first element of @_' (which is what you probably had in mind) but 'give me the number of elements in the list'. You pass the hashref \%white to the sub, so @_ contains one element, i.e. 1 is being assigned to $ref_color, hence the error message 'Can't use string ("1")...'. What you want to do is either:
1 - The C way : my $ref_color = $_[0]; or
2 - The Perl way: my $ref_color = shift;
shift() operates on @_ if no additional arguments are given and you should use it instead of accessing individual array elements by their subscripts, which is slower.
perldsc is also a good reference if you run into trouble with hashes of hashes or other data structures.
 
S

Sven-Thorsten Fahrbach

Yes you're a Genious so simple but took me some hours of my life seeking
in the docs

Thanks a lot

Regards Daniel

This won't be the last time you encounter something like that ;-). It's often the most simple things that take longest to fix.
Happy coding.

SveTho
 
T

Tom

Sven-Thorsten Fahrbach said:
Wrong context. This doesn't mean 'give me the first element of @_' (which
is what you probably had in mind) but 'give me the number of elements in the
list'. You pass the hashref \%white to the sub, so @_ contains one element,
i.e. 1 is being assigned to $ref_color, hence the error message 'Can't use
string ("1")...'. What you want to do is either:
1 - The C way : my $ref_color = $_[0]; or
2 - The Perl way: my $ref_color = shift;
shift() operates on @_ if no additional arguments are given and you should
use it instead of accessing individual array elements by their subscripts,
which is slower.
perldsc is also a good reference if you run into trouble with hashes of
hashes or other data structures.

I am still having trouble with why "1" is not X0001
or some such.
 
A

Anno Siegel

Tom said:
[...]
Wrong context. This doesn't mean 'give me the first element of @_' (which
is what you probably had in mind) but 'give me the number of elements in the
list'. You pass the hashref \%white to the sub, so @_ contains one element,
i.e. 1 is being assigned to $ref_color, hence the error message 'Can't use
string ("1")...'. What you want to do is either:
[...]

I am still having trouble with why "1" is not X0001
or some such.

$ref_color becomes the number of elements in the array @_. In the given
case the number is 1. It is not X0001 and will never be.

Anno
 
I

Ian Wilson

Anno said:
Tom said:

[...]

my $ref_color = @_;

Wrong context. This doesn't mean 'give me the first element of @_' (which

is what you probably had in mind) but 'give me the number of elements in the
list'. You pass the hashref \%white to the sub, so @_ contains one element,
i.e. 1 is being assigned to $ref_color, hence the error message 'Can't use
string ("1")...'. What you want to do is either:

[...]


I am still having trouble with why "1" is not X0001
or some such.


$ref_color becomes the number of elements in the array @_. In the given
case the number is 1. It is not X0001 and will never be.

It seems to me that Tom's question was about the internal representation
hinted at by the error message. The number of elements in an array is an
integer so why does the error message mention a string? Why seemingly
hex 0x31 and not hex 0x01?

Anno's answer still applies of course but doesn't shed much light on
perl's choice of internal representations.

I suspect the error message is mainly saying that the thing was not a
hash ref. Perl seems happy to transform string representations of
numbers into numbers as needed for arithmentic etc. As an
unsophisticated programmer of Perl I mostly don't need to know or care
about whether perl stores numbers as strings internally.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Sorting hash of hashes 3
process multiple hashes 5
Sorting hash of hashes 9
hash of hashes 9
ordered hashes 13
Parsing an Array of Hashes 3
Access hash of hashes element problem. 9
Hash of hashes 5

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top