Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello,
I have the following situation:
I create a class by means of Class::Base mechanism.

The method init() should be overriden in order to initialize my own object:

sub init { my ($self, $config) = @_; @$self{ keys %$config } = values %$config; $self->{ sql } = $SQL; $self->connect( ) || return; return $self; }

This method it is called internally by the new() constructor, where bless function returns the reference object associating the reference to the anonymous hash with invocant $class, thus all accesses to the internal glob of data will be through the invocant $class.

Next, init() method it is called:

$self->init($config);

This is the new() constructor taken from the source:

sub new { my $class = shift; # allow hash ref as first argument, otherwise fold args + # into hash my $config = defined $_[0] && UNIVERSAL::isa($_[0], 'HASH') ? shift : { @_ }; no strict 'refs'; my $debug = defined $config->{ debug } ? $config->{ debug } : defined $config->{ DEBUG } ? $config->{ DEBUG } : ( ${"$class\::DEBUG"} || 0 ); my $self = bless { _ID => $config->{ id } || $config->{ ID } || $class, _DEBUG => $debug, _ERROR => '', }, $class; return $self->init($config) || $class->error($self->error()); }

My question is: What does the following line of code :

@$self{ keys %$config } = values %$config;

Because it seems to dereference an array that is a value in the hash refered to by $self.

But keys %$config, returns an array of keys from the dereferenced hash refered to by $config and values %$config, returns an array of values from the dereferenced hash refered to by $config.

Is this creating pairs such thsi key_i => [value_i] foreach key and value elements?

Could anybody translate for me that line of code, please?

Thank you

20060906 Janitored by Corion: Removed H2, Added formatting, remoded code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: Hash assignment misunderstanding
by wfsp (Abbot) on Sep 06, 2006 at 09:14 UTC
    Is this creating pairs such as key_i => [value_i] foreach key and value elements?
    Yes. It uses a hash slice. It is a way of adding too/overwriting the initial keys/values using another hash. It may be easier to see an example:
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my $default = { one => 1, two => 2, three => 3, }; my $config = { one => 100, two => 200, }; @$default{ keys %$config } = values %$config; print Dumper $default; __DATA__ output: $VAR1 = { 'three' => 3, 'one' => 100, 'two' => 200 };

    update: added a link to the docs

      Thank you very much for your help
      I would also be very suspicious of relying on keys and values having the same order, they probably will (might even be guaranteed) but I'd still prefer not to have an unsorted keys call as a hash slice. Instead of:
      @$default{ keys %$config } = values %$config;
      ...I'd probably write:
      my @ids = keys %$config; @$default{ @ids } = @$config{ @ids };
      ...this is also less likely to get updated to be "bad".
      --
      And-httpd, $2,000 security guarantee
      James Antill

        keys() and values() are guarenteed to be the same as long as you don't modify the hash in between calls.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

        From the docs:

        The keys are returned in an apparently random order, but it is the same order as either the values() or each() function produces (given that the hash has not been modified).