Damiii
Damiii

Reputation: 1373

How to use a Perl global hash

I'm having a problem with Perl. It's giving me an error that I don't understand.

This is my program

our $neighbor = {};

$$neighbor{'a'} = 'b';

print Dumper($vizinho);

sub keyboard{
    my ($a,$b) = @_;
    return 4 if ($a eq $b);
    return 2 if $neighbor{$a}{$b};
    return -1;
}

And my error is

Variable "%vizinho" is not imported at t/DistStr.t line 30.
Global symbol "%vizinho" requires explicit package name at t/DistStr.t line 30.
Execution of t/DistStr.t aborted due to compilation errors.
# Looks like your test exited with 255 just after 1.

What I want to do is

use Alinhamento;

$neighbor = ... # Something which will create an hash where
                # $neighbor{$x}{$y} exists if the letter $x is neighbour of $y 

sub keyboard {
    my ($a, $b) = @_;
    return 4 if ($a eq $b);
    return 2 if $neighbor{$a}{$b};  #And use that $neighbor on that function
    return -1;
}

But I don't know how to make that. May I have some advice please?

Upvotes: 1

Views: 2435

Answers (3)

Miller
Miller

Reputation: 35198

With the below line you create a scalar to a hash reference:

our $neighbor = {};

What I suspect you want is just a hash

our %neighbor = (
    'foo' => {
        'bar' => 1,
    },
    'biz' => {
        'baz' => 1,
    },
);

sub keyboard {
    my ($key1, $key2) = @_;
    return 4 if ($key1 eq $key2);
    return 2 if $neighbor{$key1}{$key2};  #And use that $neighbor on that function
    return -1;
}

Also note that $a and $b are special variables used by perl's sort function, so it's probably best to use another variable name for clarity.

Upvotes: 1

Borodin
Borodin

Reputation: 126722

You must start every Perl program with

use strict;
use warnings;

and many problems will resolve themselves.

You use package (global) variables in the same way as any other variable. In fact, if you have been used to not using strict, then all of your variables have probably been package variables.


Update

To set element x, y of your hash so that it exists and is true, you should write

$vizinho->{$x}{$y} = 1;

Your problem seems to be with how to use references. You declare

our $vizinho = {}

and then try to assign to it using

$$vizinho{'a'} = 'b'

which is wrong. You could write

${$vizinho}{'a'} = 'b'

or, much better

$vizinho->{a} = 'b'

You also shouldn't ever use $a or $b. Your code should look like this

use strict;
use warnings;

our $vizinho = {};

$vizinho->{a} = 'b';

sub keyboard {
  my ($meu_a, $meu_b) = @_;
  return 4 if $meu_a eq $meu_b;
  return 2 if $vizinho->{$meu_a} eq $meu_b;
  return -1;
}

Upvotes: 3

codnodder
codnodder

Reputation: 1675

There are a number of approaches, depending on specifics that are not apparent in the context provided. Here is one simple approach loosely based on your original posting:

use Data::Dumper;

our %neighbor;

$neighbor{'a'}{'b'} = 1;

print Dumper(\%neighbor);

sub keyboard{
    my ($a, $b) = @_;
    return  4 if ($a eq $b);
    return  2 if $neighbor{$a}{$b};
    return -1;
}

EDIT: Renamed $vizinho to %neighbor. Thanks @Borodin.

Note $a and $b are a little special in Perl. See the documentation for sort.

Upvotes: 4

Related Questions