Skip to content
New issue

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

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

Already on GitHub? Sign in 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

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

No branches or pull requests

3 participants