Mailing List Archive

push HASH, LIST
We now have key-value slices.

$ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
a
6
b
7

So we can easily retrieve a list of key-value pairs. Adding key-value pairs
to a hash, on the other hand, isn't as nice. Do so requires

my %kvpairs = @kvpairs;
@h{ keys(%kvpairs) } = values(%kvpairs);

or

use List::Util qw( pairkeys pairvalues );

@h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);

or

%h = ( %h, @kvpairs );

None of those are great. Would there be any problems with supporting

push %hash, @kvpairs;

and of course

push $hash->%*, @kvpairs;

These are currently compilation errors. These do not have the same problem
as `push REF, LIST` had (which was that certain references can be
considered both a hash and an array).

- Eric "ikegami" Brine
Re: push HASH, LIST [ In reply to ]
Hi Eric!

On Tue, 4 Aug 2020 17:00:44 -0400
Eric Brine <ikegami@adaelis.com> wrote:

> We now have key-value slices.
>
> $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
> a
> 6
> b
> 7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value pairs
> to a hash, on the other hand, isn't as nice. Do so requires
>
> my %kvpairs = @kvpairs;
> @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
> use List::Util qw( pairkeys pairvalues );
>
> @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
> %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
> push %hash, @kvpairs;
>
> and of course
>
> push $hash->%*, @kvpairs;
>

I recall suggesting that in the past, and others may have suggested it before
me. Some of the porters objected to this request back then, but I'd still be
interested in such an addition.

> These are currently compilation errors. These do not have the same problem
> as `push REF, LIST` had (which was that certain references can be
> considered both a hash and an array).
>
> - Eric "ikegami" Brine



--

Shlomi Fish https://www.shlomifish.org/
List of Text Processing Tools - https://shlom.in/text-proc

95% of Programmers consider 95% of the code they did not write, in the bottom
5%.
https://www.shlomifish.org/humour.html

Please reply to list if it's a mailing list post - https://shlom.in/reply .
Re: push HASH, LIST [ In reply to ]
On 4/8/20 23:00, Eric Brine wrote:
> We now have key-value slices.
>
>     $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
>     a
>     6
>     b
>     7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value
> pairs to a hash, on the other hand, isn't as nice. Do so requires
>
>     my %kvpairs = @kvpairs;
>     @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
>     use List::Util qw( pairkeys pairvalues );
>
>     @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
>     %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
>     push %hash, @kvpairs;
>
> and of course
>
>     push $hash->%*, @kvpairs;

Then, I think that for consistence, unshift should also be extended:

unshift %hash, @list

So that if "push %h, @l" is equivalent to "%h = (%h, @l)", then "unshift
%h, @l" is "%h = (@l, %h)"

Though, I don't think "unshift" is a good name for that operation.
Re: push HASH, LIST [ In reply to ]
On 4/8/20 23:00, Eric Brine wrote:
> We now have key-value slices.
>
>     $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
>     a
>     6
>     b
>     7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value
> pairs to a hash, on the other hand, isn't as nice. Do so requires
>
>     my %kvpairs = @kvpairs;
>     @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
>     use List::Util qw( pairkeys pairvalues );
>
>     @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
>     %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
>     push %hash, @kvpairs;
>
> and of course
>
>     push $hash->%*, @kvpairs;

Then, I think that for consistence, unshift should also be extended:

unshift %hash, @list

So that if "push %h, @l" is equivalent to "%h = (%h, @l)", then "unshift
%h, @l" is "%h = (@l, %h)"

Though, I don't think "unshift" is a good name for that operation.
Re: push HASH, LIST [ In reply to ]
On 4/8/20 23:00, Eric Brine wrote:
> We now have key-value slices.
>
>     $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
>     a
>     6
>     b
>     7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value
> pairs to a hash, on the other hand, isn't as nice. Do so requires
>
>     my %kvpairs = @kvpairs;
>     @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
>     use List::Util qw( pairkeys pairvalues );
>
>     @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
>     %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
>     push %hash, @kvpairs;
>
> and of course
>
>     push $hash->%*, @kvpairs;

Then, I think that for consistence, unshift should also be extended:

unshift %hash, @list

So that if "push %h, @l" is equivalent to "%h = (%h, @l)", then "unshift
%h, @l" is "%h = (@l, %h)"

Though, I don't think "unshift" is a good name for that operation.
Re: push HASH, LIST [ In reply to ]
On 4/8/20 23:00, Eric Brine wrote:
> We now have key-value slices.
>
> $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
> a
> 6
> b
> 7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value
> pairs to a hash, on the other hand, isn't as nice. Do so requires
>
> my %kvpairs = @kvpairs;
> @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
> use List::Util qw( pairkeys pairvalues );
>
> @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
> %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
> push %hash, @kvpairs;
>
> and of course
>
> push $hash->%*, @kvpairs;

Then, I think that for consistence, unshift should also be extended:

unshift %hash, @list

So that if "push %h, @l" is equivalent to "%h = (%h, @l)", then "unshift
%h, @l" is "%h = (@l, %h)"
Re: push HASH, LIST [ In reply to ]
On Tue, 4 Aug 2020 17:00:44 -0400
Eric Brine <ikegami@adaelis.com> wrote:

> %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
> push %hash, @kvpairs;
>
> and of course
>
> push $hash->%*, @kvpairs;

I like the idea of an "add more pairs to a hash" operator, but I don't
like naming it "push". That sort of overloading of operator names
reminds me of the great deref/keys/values clash of a few versions ago,
which was regrettable.

If anything, your first line using the comma operator suggests a new
mutating-comma operator of

%h ,= @kvpairs;

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: push HASH, LIST [ In reply to ]
On Wed, 5 Aug 2020 at 17:23, Salvador Fandiño <sfandino@gmail.com> wrote:

> Then, I think that for consistence, unshift should also be extended:
>
> unshift %hash, @list
>
> So that if "push %h, @l" is equivalent to "%h = (%h, @l)", then "unshift
> %h, @l" is "%h = (@l, %h)"
>
> Though, I don't think "unshift" is a good name for that operation.
>

Seems reasonable, both versions have their uses.

It'd be important to note in the documentation that

push %h, @l;

is *not* directly equivalent to

%h = (%h, @l);

for at least two reasons:

- push on an array returns the number of elements, we'd likely want to have
something similar here? the %h = version returns the full key-value list
- push would not be expected to reässign any elements, including changing
any weakrefs:

my %h; weaken($h{example} = my $v = []); push %h, other => 'data';
ok(isweak($h{example}));
Re: push HASH, LIST [ In reply to ]
# You can do this in pure Perl.

use strict;
use warnings;

package Acme::HashPush;

BEGIN {
our $VERSION = "0.001";
}

sub hpush (\%@)
{
my($h) = @_;

if ($#_ & 1) {
push(@_, undef);
warnings::warnif(
misc => "Odd number of elements in hash assignment");
}
for (my $i = 1; $i < $#_; $i += 2) {
$h->{$_[$i]} = $_[$i+1];
}
}

sub hunshift (\%@)
{
my($h) = @_;

if ($#_ & 1) {
push(@_, undef);
warnings::warnif(
misc => "Odd number of elements in hash assignment");
}
for (my $i = $#_-1; $i > 0; $i -= 2) {
exists($h->{$_[$i]})
or $h->{$_[$i]} = $_[$i+1];
}
}

BEGIN {
our @EXPORT = our @EXPORT_OK = qw(hpush hunshift);
}

use Exporter
qw(import);

1;
Re: push HASH, LIST [ In reply to ]
Shorter yet, if it were legal:

%h += @kvpairs;

Currently this operation is a syntax error, so its available for use:

use Data::Dump qw(dump);

my @a = qw(a 1 b 2);
my @b = qw(c 3 d 4);
my %h = @a;
say STDERR dump(\%h); # { a => 1, b => 2 }
%h += @b; # Can't modify private hash in addition

On Tue, Aug 4, 2020 at 10:01 PM Eric Brine <ikegami@adaelis.com> wrote:

> We now have key-value slices.
>
> $ perl -e'%h=(a=>6,b=>7,c=>8); CORE::say for %h{qw( a b )};'
> a
> 6
> b
> 7
>
> So we can easily retrieve a list of key-value pairs. Adding key-value
> pairs to a hash, on the other hand, isn't as nice. Do so requires
>
> my %kvpairs = @kvpairs;
> @h{ keys(%kvpairs) } = values(%kvpairs);
>
> or
>
> use List::Util qw( pairkeys pairvalues );
>
> @h{ pairkeys(@kvpairs) } = pairvalues(@kvpairs);
>
> or
>
> %h = ( %h, @kvpairs );
>
> None of those are great. Would there be any problems with supporting
>
> push %hash, @kvpairs;
>
> and of course
>
> push $hash->%*, @kvpairs;
>
> These are currently compilation errors. These do not have the same problem
> as `push REF, LIST` had (which was that certain references can be
> considered both a hash and an array).
>
> - Eric "ikegami" Brine
>
>

--
Thanks,

Phil <https://metacpan.org/author/PRBRENAN>

Philip R Brenan <https://metacpan.org/author/PRBRENAN>
Re: push HASH, LIST [ In reply to ]
On Wed, 5 Aug 2020 16:04:33 +0100, Philip R Brenan
<philiprbrenan@gmail.com> wrote:

> Shorter yet, if it were legal:
>
> %h += @kvpairs;

%h += @kvpairs; # ADD do not replace
%h |= @kvpairs; # ADD or REPLACE
%h -= @keys; # short for delete %h{@keys}

> Currently this operation is a syntax error, so its available for use:
>
> use Data::Dump qw(dump);
>
> my @a = qw(a 1 b 2);
> my @b = qw(c 3 d 4);
> my %h = @a;
> say STDERR dump(\%h); # { a => 1, b => 2 }
> %h += @b; # Can't modify private hash in addition

--
H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/
using perl5.00307 .. 5.31 porting perl5 on HP-UX, AIX, and Linux
https://useplaintext.email https://tux.nl http://www.test-smoke.org
http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/