Question about hashes of hashes

Discussion in 'Perl Misc' started by djacober, Jul 24, 2005.

  1. djacober

    djacober Guest

    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
     
    djacober, Jul 24, 2005
    #1
    1. Advertising

  2. djacober wrote:
    >
    > 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.


    <random code snippets snipped>

    > 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!

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 24, 2005
    #2
    1. Advertising

  3. djacober wrote:
    > Gunnar Hjalmarsson wrote:
    >> djacober wrote:
    >>> 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!

    >
    > Sorry I didn't want to overload with code:
    >
    > Here's the complete code


    Well, I didn't ask for the _complete_ code either. ;-)

    Now, Sven-Thorsten found the mistake anyway, but for next time, please
    study the posting guidelines for this group to better understand what I
    was after.

    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 24, 2005
    #3
  4. djacober

    djacober Guest

    Gunnar Hjalmarsson wrote:
    > djacober wrote:
    >
    >>
    >> 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.

    >
    >
    > <random code snippets snipped>
    >
    >> 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!
    >


    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();
     
    djacober, Jul 24, 2005
    #4
  5. djacober

    djacober Guest

    Sven-Thorsten Fahrbach wrote:
    > On Sun, 24 Jul 2005 22:39:31 +0200
    > djacober <> wrote:
    >
    >
    >>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
     
    djacober, Jul 24, 2005
    #5
  6. Sven-Thorsten Fahrbach wrote:
    > djacober wrote:
    >>
    >>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

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 24, 2005
    #6
  7. On Sun, 24 Jul 2005 22:39:31 +0200
    djacober <> wrote:

    > 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.
     
    Sven-Thorsten Fahrbach, Jul 24, 2005
    #7
  8. On Sun, 24 Jul 2005 22:57:44 +0200
    djacober <> wrote:

    > 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
     
    Sven-Thorsten Fahrbach, Jul 24, 2005
    #8
  9. djacober

    Tom Guest

    "Sven-Thorsten Fahrbach" <> wrote in message
    news:...
    > On Sun, 24 Jul 2005 22:39:31 +0200
    > djacober <> wrote:
    >
    > > 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.

    I am still having trouble with why "1" is not X0001
    or some such.
     
    Tom, Jul 24, 2005
    #9
  10. djacober

    Anno Siegel Guest

    Tom <> wrote in comp.lang.perl.misc:
    > "Sven-Thorsten Fahrbach" <> wrote in message
    > news:...
    > > On Sun, 24 Jul 2005 22:39:31 +0200
    > > djacober <> wrote:


    [...]

    > > > 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.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Jul 25, 2005
    #10
  11. djacober

    Ian Wilson Guest

    Anno Siegel wrote:
    > Tom <> wrote in comp.lang.perl.misc:
    >
    >>"Sven-Thorsten Fahrbach" <> wrote in message
    >>news:...
    >>
    >>>On Sun, 24 Jul 2005 22:39:31 +0200
    >>>djacober <> wrote:

    >
    >
    > [...]
    >
    >
    >>>> 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.
     
    Ian Wilson, Jul 25, 2005
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Holness

    Hashes of Hashes via subs

    Ben Holness, Oct 5, 2003, in forum: Perl
    Replies:
    8
    Views:
    591
    Ben Holness
    Oct 8, 2003
  2. Steven Arnold

    using hashes as keys in hashes

    Steven Arnold, Nov 23, 2005, in forum: Ruby
    Replies:
    3
    Views:
    185
    Mauricio Fernández
    Nov 23, 2005
  3. kazaam
    Replies:
    12
    Views:
    295
    Matthias Wächter
    Sep 13, 2007
  4. Neela megha shyam Chivukula

    On Hashes - How the hashes printing works?

    Neela megha shyam Chivukula, May 27, 2009, in forum: Ruby
    Replies:
    4
    Views:
    280
    Markus Schirp
    May 28, 2009
  5. Tim O'Donovan

    Hash of hashes, of hashes, of arrays of hashes

    Tim O'Donovan, Oct 27, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    237
Loading...

Share This Page