Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bugs in clone, sugar methods, and postdec #6

Open
xdg opened this issue Feb 26, 2016 · 2 comments
Open

Bugs in clone, sugar methods, and postdec #6

xdg opened this issue Feb 26, 2016 · 2 comments

Comments

@xdg
Copy link
Contributor

xdg commented Feb 26, 2016

Hi David,

A. The clone method upon receiving duplicate keys returns a cloned object with duplicate keys inside [_KEYS]. This is similar to a prior bug in ->new.

$copy = $ho->clone(qw/ k1 k2 k2 k3 /); # [_KEYS] has "k2" twice

B. Sugar methods do not check if the key exists in [_DATA].

$ho = Hash::Ordered->new();
$ho->preinc("counter"); # "counter" is missing in [_KEYS]

C. ->postdec returns undef the first time. Interestingly, postinc returns 0 even though not doing // 0 or || 0 inside the code. It appears that Perl isn't consistent with post -- and ++ to an undefined value.

perli> $ho = Hash::Ordered->new
bless( [
{},
[],
undef,
0,
0
], 'Hash::Ordered' )

perli> $ho->postinc("key1")
0

perli> $ho->postdec("key2")
undef

@grr
Copy link

grr commented Feb 9, 2020

Think this is related. And it's a really common use case:

my $count = Hash::Ordered->new;
for my $k (qw(a a a b c d e e e e)) {
    $count->postinc($k);
}
say for $count->keys;

The hash ends up being empty.

But using the tied interface works as expected.

tie my %count, "Hash::Ordered";
for my $k (qw(a a a b c d e e e e)) {
    $count{$k}++;
}
say for keys %count;

Since this is a really old bug for a common use case, it should at least be documented.

@marioroy
Copy link

marioroy commented Nov 25, 2021

Hi David. I also encountered the bug with preinc not appending the key if missing. It requires one to set the value initially.

use strict; use warnings;

use Tie::Hash::Indexed;
use Hash::Ordered;
use MCE::Shared::Ordhash;

# my $hi = Tie::Hash::Indexed->new(total => 0);  # all pass
# my $ho = Hash::Ordered->new(total => 0);
# my $oh = MCE::Shared::Ordhash->new(total => 0);

my $hi = Tie::Hash::Indexed->new();  # pass
my $ho = Hash::Ordered->new();  # preinc fails
my $oh = MCE::Shared::Ordhash->new();  # pass

sub task {
    my $id = shift;
    $hi->set($id => $id); $hi->preinc('total');
    $ho->set($id => $id); $ho->preinc('total');
    $oh->set($id => $id); $oh->incr('total');
}

task($_) for 1..4;

my (@k, @v);
@k = $hi->keys; print "hi keys: @k\n";
@k = $ho->keys; print "ho keys: @k\n";
@k = $oh->keys; print "oh keys: @k\n";
@v = $hi->values; print "hi vals: @v\n";
@v = $ho->values; print "ho vals: @v\n";
@v = $oh->values; print "oh vals: @v\n";

__END__
# expected results
hi keys: total 1 2 3 4
ho keys: total 1 2 3 4
oh keys: total 1 2 3 4
hi vals: 4 1 2 3 4
ho vals: 4 1 2 3 4
oh vals: 4 1 2 3 4

# ho fails unless setting 'total' to 0 during construction or before running
ho keys: 1 2 3 4
ho vals: 1 2 3 4

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants