Pass by value vs pass by reference for Perl hash

I use a routine to create several different hash maps. I am currently passing the hashmap by reference, but this conflicts when you do this several times. Should I pass a hash by value or pass a hash link?

use strict;
use warnings;

sub fromFile($){
    local $/;
    local our %counts =();
     my $string = <$_[0]>;
    open FILE, $string or die $!;
    my $contents = <FILE>;
    close FILE or die $!;

    my $pa = qr{
        ( \pL {2} )
        (?{
            if(exists $counts{lc($^N)}){
                $counts{lc($^N)} = $counts{lc($^N)} + 1;
            }
            else{
                $counts{lc($^N)} = '1';
            }
        })
        (*FAIL)
    }x;

     $contents =~ $pa;

    return %counts;

}

sub main(){
    my %english_map = &fromFile("english.txt");
    #my %german_map = &fromFile("german.txt");
}

main();

When I run different txt files separately, I don't get any problems, but I get some conflicts with both.

+5
source share
3 answers

For several reasons, you should use pass-by-reference, but the displayed code returns a hash by value.

  • You should use my, and not local, with the exception of built-in variables such as $/, and then only for a small scope.

  • . - , , , .

  • , &fromFile("english.txt"), Perl 4, . , , , .

  • , glob my $string = <$_[0]>. , ? , , glob .

  • , $fh, , FILE, , - , .

  • , %counts. , !

. , Perl, (!) , . main. C, Perl.

. , , .

use strict;
use warnings;

sub from_file {

    my ($filename) = @_;

    my $contents = do {
        open my $fh, '<', $filename or die qq{Unable to open "$filename": $!};
        local $/;
        my $contents = <$fh>;
    };

    my %counts;
    $counts{lc $1}++ while $contents =~ /(?=(\pL{2}))/g;

    return \%counts;
}

sub main {
    my $english_map = from_file('english.txt');
    my $german_map  = from_file('german.txt');
}

main();
+9

:

- , ( ).

, .

, .

Perl

( @_) . , .

my ($x, $y) = @_;   # This copies the args.

, "" , , @_ .

$ perl -E'sub f { my ($x) = @_; "b"=~/(.)/; say $x;    } "a"=~/(.)/; f($1)'
a

$ perl -E'sub f {               "b"=~/(.)/; say $_[0]; } "a"=~/(.)/; f($1)'
b

Perl

, Perl sub, . ( , .)

@a $a[0], $a[1], ... ,

foo(@a)

foo($a[0], $a[1], ...)

, .

, , sub. , ,

foo(@a, @b)

foo , @a @b.

, , /, , .

+11

, . . , :

Perl . . , , . :

foo(@first, @second);

, , - , . . , , :

@common_keys = common(%hash1, %hash1);

, .

- :

foo(\@first, \@second);
@common_keys = common(\%hash1, \%hash2);

, . -. , , .

- . - , . , 10 000 000 . . , , . . .

, , . , .

#! /usr/bin/env perl
use strict;
use warnings;

my @array = qw(this that the other);

foo (@array);

print join ( ":", @array ) . "\n";

sub foo {
    my @foo_array = @_;
    $foo_array[1] = "FOO";
}

, foo 1 . , @array foo, @array. , ( my @foo_array = @_;). , .

, :

this:that:the:other

, , , , , :

#! /usr/bin/env perl
use strict;
use warnings;

my @array = qw(this that the other);

foo (\@array);

print join ( ":", @array ) . "\n";

sub foo {
    my $foo_array_ref = shift;
    $foo_array_ref->[1] = "FOO";
}

, :

this:FOO:the:other

, , . , @array. , . .

, , . , :

sub foo {
    my @foo_array = @{ shift() };

. , , , . 1980- , , . Quadcore , . 10 , , , .

. . , .

- Perl . , , .

. ( ). , . :

return $self->{COUNT_HASH};

, , ? , . , , . , :

my %hash_counts = % { $self-{COUNT_HASH} };
return \%hash_count;

, . . , , .

, wantarray, , :

my %hash_counts = %{ $self->{COUNT_HASH} };
return want array ? %hash_counts : \%hash_counts;

, :

my %hash_counts = $object->totals();      # Returns a hash
my $hash_counts_ref = $object->totals();  # Returns a reference to a hash

1 : @_ , . , foo(@array), $_[1] = "foo";, @array.

+3

All Articles