in reply to Re^3: Hash/Array slice : how to exclude items?
in thread Hash/Array slice : how to exclude items?

> Shouldn't this work?:

> print Dumper(do { delete local  @$hashref{ @$bad_keys }, $hashref} ); or this print Dumper(do { delete local  @$hashref{ @$bad_keys }; $hashref} );

yes it's surprising.

One needs to remember that local is protecting certain entries and not the whole hash (The hash could be a lexical variable, local wouldn't do anyway)

Since you are returning a reference, you'll see the restored entries again after leaving the block.

consider what's happening without delete

DB<91> use Data::Dump qw/pp/ DB<92> ; {local @hash{qw/log schema/};say pp \%hash}; say pp \%hash { a => 1, b => 2, c => 3, log => undef, schema => undef } { a => 1, b => 2, c => 3, log => "l", schema => "s" }

you can still have the desired effect by just returning a list or a new anonymous hash

DB<96> say pp do {delete local @hash{qw/log schema/}; %hash }; say +pp \%hash ("a", 1, "c", 3, "b", 2) { a => 1, b => 2, c => 3, log => "l", schema => "s" } DB<97> say pp do {delete local @hash{qw/log schema/}; +{%hash} }; s +ay pp \%hash { a => 1, b => 2, c => 3 } { a => 1, b => 2, c => 3, log => "l", schema => "s" } DB<98>

if you shy away from the overhead to return a new hash, just do the dumping inside the block.

DB<99> ; {delete local @hash{qw/log schema/};say pp \%hash}; say pp +\%hash { a => 1, b => 2, c => 3 } { a => 1, b => 2, c => 3, log => "l", schema => "s" } DB<100>

HTH! :)

Cheers Rolf
(addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^5: Hash/Array slice : how to exclude items?
by bliako (Abbot) on Jan 25, 2023 at 09:01 UTC
    if you shy away from the overhead to return a new hash,

    yes, that's one of my fetishes. But as you and hv said: do the printing in the block. It sounds a bit excessive but it seems a good candidate now, along with the slice-with-grep-keys. Given that I may use a number of "printers" : print, say, Dumper, Mojo::Log, then I would not want a special sub which hardcodes the logger.

    One purpose of this post was to nudge Perl language developers to consider exclude-slices, with maximum elegance and minimum overhead (Logging like this happens every few lines of code for me). Btw, the negation with ! looks nice.

    Btw2, is anyone aware of another language implementing this? I googled pithon and did not see something.

      > Btw, the negation with ! looks nice.

      I'm not sure about this anymore, it's already legal syntax and could conflict with older code.

      DB<33> $h{!A}=1 DB<34> $h{!(A)}=1 DB<35> $h{!("A")}=1 DB<36> x \%h 0 HASH(0x32dad38) '' => 1 DB<37>

      One could consider something like @h!{LIST}

      DB<40> @h!{"A"} = (1) syntax error at ...

      But still, is adding another obscure operation to Perl worth it?

      > One purpose of this post was to nudge Perl language developers to consider exclude-slices, with maximum elegance and minimum overhead (Logging like this happens every few lines of code for me).

      I think we need a meta discuss, what "good" syntax is.

      "Elegance" alone doesn't help if the use case is so obscure that you never use it.

      For instance I saw delete local SLICE before, but didn't remember or ever used it till now.

      I'm a fan of orthogonality, the combination of syntax should be productive and easily predictive instead of being limited to isolated edge-cases.

      This special case interferes somehow with Perl's lacking abilities for set-operations.

      Probably a combined approach would be a better return of investment.

      edit

      Furthermore:

      IMHO A named "speaking" operator like ->excl would be a better choice than investing into a short symbol like '!'.

      Don't forget that various parsers like perl-tidy need to be updated if ! was introduced.

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery