7

I'm still trying to sort out my hash dereferencing. My current problem is I am now passing a hashref to a sub, and I want to dereference it within that sub. But I'm not finding the correct method/syntax to do it. Within the sub, I want to iterate the hash keys, but the syntax for a hashref is not the same as a hash, which I know how to do.

So what I want is to do this:

sub foo {
    %parms = @_;
    foreach $keys (key %parms) { # do something };
}

but with a hashref being passed in instead of a hash.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
sgsax
  • 393
  • 1
  • 4
  • 8

5 Answers5

3

I havn't actually tested the code at this time, but writing freehand you'll want to do something like this:

sub foo {
    $parms = shift;
    foreach my $key (keys %$parms) { # do something };
}
friedo
  • 65,762
  • 16
  • 114
  • 184
cyberconte
  • 2,371
  • 4
  • 21
  • 27
  • Using shift instead of @_ did the trick, and of course, using a scalar instead of a hash for the variable. Working code: sub foo { $parms = shift; foreach $key (keys %$parms) { print "$key : $$parms{$key}\n"; } } Thanks! – sgsax Feb 17 '10 at 17:52
  • 2
    `shift` vs. `@_` is not relevant. `my ($hashref) = @_;` will work just as well. – nobody Feb 18 '10 at 00:43
  • @nobody yes thx, in this context, but not to say there is no significant difference between `shift` and `@` generally. The `@` without parentheses `my $hashref = @_;` would return a scalar (=the number of parameters passed) or eventually an entire array of parameters passed used as this => `my @var = @_;` . Would work the same only/in your "destructuring" assignment way `my ($hashref) = @_;` – FantomX1 Dec 07 '21 at 10:16
2

Here is one way to dereference a hash ref passed to a sub:

use warnings;
use strict;

my %pars = (a=>1, b=>2);
foo(\%pars);
sub foo {
    my ($href) = @_;
    foreach my $keys (keys %{$href}) { print "$keys\n" }
}

__END__
a
b

See also References quick reference and perlreftut

toolic
  • 57,801
  • 17
  • 75
  • 117
2

sub foo
{
    my $params = $_[0];
    my %hash = %$params;
        foreach $keys (keys %hash)
        {
         print $keys;
        }
}

my $hash_ref = {name => 'Becky', age => 23};

foo($hash_ref);

Also a good intro about references is here.

sud03r
  • 19,109
  • 16
  • 77
  • 96
  • Thanks for the link. I've been using that one as a reference, but I still don't quite have a full grasp of it yet. – sgsax Feb 17 '10 at 17:53
1
#!/usr/bin/perl
use strict;

my %params = (
    date => '2010-02-17',
    time => '1610',
);

foo(\%params);

sub foo {
    my ($params) = @_;
    foreach my $key (keys %$params) {
        # Do something
        print "KEY: $key VALUE: $params{$key}\n";
    };
}
chris d
  • 19
  • 3
0

Dereference the original reference, but use it as another one / its copy, what is also very common or more common.

sub foo {
    my ($parmsHashRef , $parmsArrRef) = @_;

    # for hashes,   \%$parmsHashRef - would not work (seems would be a "reference" on another reference already)
    my $newDetachedHashRef = {%$parmsHashRef} # or just = {$parmsHashRef}
    # for arrays ,  \@$parmsArrRef - would not work
    my $newDetachedArrRef = [@$parmsArrRef] # or just = [$parmsArrRef]
}
Community
  • 1
  • 1
FantomX1
  • 1,577
  • 2
  • 15
  • 23