GunBlade
GunBlade

Reputation: 105

Mixed hash not working correctly

I'm creating this hash

    my %obj_cuentascontables = {
        '4210' => {
            'banderamayor' => 'true',
            'enlace' => 'true',
            'not_rlike_nombre' => 'DEVOLUCION'
    },
        '4410' => {
            'banderamayor' => 'true',
            'enlace' => 'true',
            'rlike_nombre' => 'DEVOLUCION',
            'categoria_cuenta' => 'DEVOLUCIONES REBAJAS Y DESCUENTOS'
        }
};

my %param = {
         'concepto_ID' => "$concepto_ID",
         'formato_ID' => $formato_ID,
         'obj_cuentascontables'=> { %obj_cuentascontables },
};

And later I Dump %param and i get this:

$VAR1 = {
          'concepto_ID' => '5501',
          'formato_ID' => 1001,
          'obj_cuentascontables' => {
                                      'HASH(0xf16eb70)' => undef
                                    }
        };

I can't use that 'HASH' Thing, so, i was trying to see if i was referencing incorrectly the hash and i create another one very similar.

my %obj_cuentascontables = ();
    $obj_cuentascontables{'4210'}{'banderamayor'} = 'true';
    $obj_cuentascontables{'4210'}{'enlace'} = 'true';
    $obj_cuentascontables{'4210'}{'not_rlike_nombre'} = 'DEVOLUCION';
    $obj_cuentascontables{'4410'}{'banderamayor'} = 'true';
    $obj_cuentascontables{'4410'}{'enlace'} = 'true';
    $obj_cuentascontables{'4410'}{'rlike_nombre'} = 'DEVOLUCION';
    $obj_cuentascontables{'4410'}{'categoria_cuenta'} = 'DEVOLUCIONES REBAJAS Y DESCUENTOS';

    my %param = ();
    $param{'concepto_ID'}= $concepto_ID;
    $param{'formato_ID'} = $formato_ID;
    $param{'obj_cuentascontables'} = \%obj_cuentascontables;

And then Dumper return this:

$VAR1 = {
          'concepto_ID' => 5501,
          'formato_ID' => 1001,
          'obj_cuentascontables' => {
                                      '4410' => {
                                                  'enlace' => 'true',
                                                  'rlike_nombre' => 'DEVOLUCION',
                                                  'categoria_cuenta' => 'DEVOLUCIONES REBAJAS Y DESCUENTOS',
                                                  'banderamayor' => 'true'
                                                },
                                      '4210' => {
                                                  'enlace' => 'true',
                                                  'not_rlike_nombre' => 'DEVOLUCION',
                                                  'banderamayor' => 'true'
                                                }
                                    }
        };

My question is, WHY?!!!... I want the second Dump in my first structure... It is possible?

Upvotes: 1

Views: 65

Answers (3)

David W.
David W.

Reputation: 107040

You're not using use warnings; which would have helped you see the odd-number error.

I assume you want your $param{obj_cuentascontables} to point to the hash %obj_cuentascontables. That way, you can refer to:

$param{obj_cuentascontables}->{4210}->{banderamayor}

as having the value of true.

You need to assign a reference to your %obj_cuentascontables hash for the value of the obj_cuentascontables key in your %param hash.

my %param = {
         concepto_ID          => "$concepto_ID",
         formato_ID           => $formato_ID,
         obj_cuentascontables => \%obj_cuentascontables,
};

My preference is to use the -> syntax when referring to references. Officially, these are both the same:

$param{obj_cuentascontables}->{4210}->{banderamayor}
$param{obj_cuentascontables}{4210}{banderamayor}

However, I find that using the -> syntax reminds me this is not really a hash, but a reference to a hash. This helps me get the syntax right when I build these complex data structures.

What you did was similar to this:

my $hash_address = sprintf "%s", \%obj_cuentascontables; # Stingifying the hash reference
$param{obj_cuentascontables} = { };
$param{obj_cuentascontables} = { $hash_address => };     # Not 100% Perl will parse this...

You assigned a hash reference to $param{obj_cuentascontables} which is what you want, but you then used the address of the hash as the key, and no value.

Upvotes: 0

ikegami
ikegami

Reputation: 385764

Always use use strict; use warnings;! The latter would have identified the error.

$ perl -e'use strict; use warnings; my %obj_cuentascontables = { };'
Reference found where even-sized list expected at -e line 1.

You are assigning a hash reference to a list when it expects a list of scalars to use as keys and values. Keep in mind that

{ ... }

is roughly

do { my %anon = ( ... ); \%anon }

so

my %obj_cuentascontables = { ... };

should be

my %obj_cuentascontables = ( ... );

Upvotes: 4

Zaid
Zaid

Reputation: 37146

If you look carefully at how you constructed the hash in the first snippet, you used curly braces {}. In the context of your assignment, this is assigning a hash reference to your hash.

What you need are round brackets ():

my %obj_cuentascontables = (
    '4210' => {
            'banderamayor' => 'true',
            'enlace' => 'true',
            'not_rlike_nombre' => 'DEVOLUCION'
    },
    '4410' => {
            'banderamayor' => 'true',
            'enlace' => 'true',
            'rlike_nombre' => 'DEVOLUCION',
            'categoria_cuenta' => 'DEVOLUCIONES REBAJAS Y DESCUENTOS'
    }
);

This is why you should use warnings;, as it would warn you about this:

Reference found where even-sized list expected ...

Upvotes: 5

Related Questions