Dereferencing hash without creating a local copy

Code line 9 below creates a local copy of the hash. Any changes to% d will not contain changes to the global variable% h (line: 5). I have to use the link (line: 8) to make changes to% h.

Is there any way to hash dereferencing in sub without creating a local copy? I ask because I have a complicated record with many links, and moving around it using breaks would be much easier.

  1 #!/usr/bin/perl -w
  2 use strict;
  3 use warnings;
  4 
  5 my %h;
  6 sub a {
  7 
  8     my $href = shift;
  9     my(%d) = %{$href};   # this will make a copy of global %h
 10     
 11     $$href{1}=2;     # this will make a change in global %h
 12     $d{2}=2;         # this will not a change in global %h
 13 }   
 14 a(\%h);
 15 print scalar (keys %h) . "\n";

----------------

Thanks for answers.

The question is, can I do some kind of "alias / binding" to% h in sub. I would like to change the context of% h to sub from% d. Whenever I create% d, it makes a local copy of% h - is there a way to avoid this, or do I need to constantly use links?

----------------

:) , $href. // .. - , , , .

:

  6 sub a {
  7     $h{"1"}=2;
  8 }

:

  6 sub a {
  8      my $href = shift;
  11     $$href{1}=2;     # this will make a change in global %h
  11     $href->{1}=2;    # this will make a change in global %h

, % d - ?

6 sub a {
7        my %d = XXXXXXXXX
.. }

XXXXXXXXX, % h ?

+3
4

, Perl, , typeglob ( local ):

#!/usr/bin/perl -w
use strict;
use warnings;

my %h;

sub a {
    my $href = shift;

    our %alias; # create the package variable (for strict)

    local *alias = $href;
        # here we tell perl to install the hashref into the typeglob 'alias'
        # perl will automatically put the hashref into the HASH slot of
        # the glob which makes %alias refer to the passed in hash.
        # local is used to limit the change to the current dynamic scope.
        # effectively it is doing:  *{alias}{HASH} = $href

    $$href{1}=2;     # this will make a change in global %h
    $alias{2}=2;     # this will also make a change in global %h
}
a(\%h);
print scalar (keys %h) . "\n";  # prints 2

, Perl local typeglobs, , ( , , a local %alias , local . , a .)

Data::Alias CPAN, . - .

+6

-:

  • $$ href {'key2'} = "key2";

  • :

    $href β†’ {'key1'} = "key1";

http://perldoc.perl.org/perlreftut.html

+2

$href->{1} = 2;
print scalars (keys %{$href});

?

+1

, ( , )

Read this for a tutorial on dereferencing and possible types of dereferencing.

use warnings;
use Data::Dumper::Simple;

my %h;
sub a {
    my $href = shift;

    #dereference using the arrow operator - *preferred*
    $href->{name} = "John"; 

}

a(\%h); #Passing the reference of the hash
print Dumper(%h);

Why do you need to pass a hash that is global as an argument to the routine in the first place?

  • Avoid using global variables.
  • It is not recommended to change the state of any variables after they are assigned.
0
source

Source: https://habr.com/ru/post/1748483/


All Articles