1

This may be something very simple for you but i have been trying for it for more than one hour.

Ok.. Here is my code,

@collection = [
{
            'name' => 'Flo',
            'model' => '23423',
            'type' => 'Associate',
            'id' => '1-23928-2392',
            'age' => '23',
},
{
            'name' => 'Flo1',
            'model' => '23424',
            'type' => 'Associate2',
            'id' => '1-23928-23922',
            'age' => '25',
}];

foreach my $row (@collection) {
  $build_status = $self->build_config($row);
}

sub build_config {
    my $self = shift;
    my %collect_rows = @_;
    #my %collect_rows = shift;

    print Dumper %collect_rows; exit;
    exit;
}

Where $row is really an Hash. But when i Print it.. It gives output like below (I am using Dumper),

$VAR1 = 'HASH(0x20a1d68)';
2
  • I'm guessing you really have @collection = ( ... ), not @collection = [ ... ]. Otherwise you would get something like $VAR1 = 'ARRAY(0x20a1d68)';. Commented Jul 29, 2016 at 21:22
  • ha.. what is that difference between them? ( ... ) is for Hash and [ ... ] is for Array. Am i right? Because declared like this @collection = [ ... ] in the code. Commented Jul 29, 2016 at 21:24

1 Answer 1

5

You are confusing references with hashes and arrays.

An array is declared with:

my @array = (1, 2, 3);

A hash is declared with:

my %hash = (1 => 2, 3 => 4);

That's because both hashes and arrays are simply lists (fancy lists, but I digress). The only time you need to use the [] and {} is when you want to use the values contained in the list, or you want to create a reference of either list (more below).

Note that the => is just a special (ie. fat) comma, that quotes the left-hand side, so although they do the same thing, %h = (a, 1) would break, %h = ("a", 1) works fine, and %h = (a => 1) also works fine because the a gets quoted.

An array reference is declared as such:

my $aref = [1, 2, 3];

...note that you need to put the array reference into a scalar. If you don't and do it like this:

my @array = [1, 2, 3];

... the reference is pushed onto the first element of @array, which is probably not what you want.

A hash reference is declared like this:

my $href = {a => 1, b => 2};

The only time [] is used on an array (not an aref) is when you're using it to use an element: $array[1];. Likewise with hashes, unless it's a reference, you only use {} to get at a key's value: $hash{a}.

Now, to fix your problem, you can keep using the references with these changes:

use warnings;
use strict;

use Data::Dumper;

# declare an array ref with a list of hrefs

my $collection = [
    {
        'name' => 'Flo',
        ...
    },
    {
        'name' => 'Flo1',
        ...
    }
];

# dereference $collection with the "circumfix" operator, @{}
# ...note that $row will always be an href (see bottom of post)

foreach my $row (@{ $collection }) {
    my $build_status = build_config($row);
    print Dumper $build_status;
}

sub build_config {
    # shift, as we're only accepting a single param...
    # the $row href

    my $collect_rows = shift;
    return $collect_rows;
}

...or change it up to use non-refs:

my @collection = (
    {
        'name' => 'Flo',
        ...
    },
    {
        'name' => 'Flo1',
        ...
    }
);

foreach my $row (@collection) {
    my $build_status = build_config($row);

    # build_config() accepts a single href ($row)
    # and in this case, returns an href as well

    print Dumper $build_status;
}

sub build_config {
    # we've been passed in a single href ($row)

    my $row = shift;

    # return an href as a scalar

    return $row;
}

I wrote a tutorial on Perl references you may be interested in guide to Perl references. There's also perlreftut.

One last point... the hashes are declared with {} inside of the array because they are indeed hash references. With multi-dimentional data, only the top level of the structure in Perl can contain multiple values. Everything else underneath must be a single scalar value. Therefore, you can have an array of hashes, but technically and literally, it's an array containing scalars where their value is a pointer (reference) to another structure. The pointer/reference is a single value.

Sign up to request clarification or add additional context in comments.

2 Comments

because it wasn't part of the question I won't explain in great detail, I will say this... refs are often the preferred way to go when passing data around, as when passing arrays or hashes around, it results in perl having to make copies of the structures instead of just sending a pointer. When you work on a ref, you work on the original structure. A case where you want to send in the actual variable is when you need a copy made, so the original structure isn't modified in the work you need to do.
[] is also uses for slices. Also, $aref->@[] is equivalent to @$aref. Similarly for hashes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.