Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

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

by bliako (Monsignor)
on Jan 24, 2023 at 22:44 UTC ( [id://11149848]=note: print w/replies, xml ) Need Help??


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

delete local looks promising, thanks haukex and ikegami. If only delete returned the remaining hash. Shouldn't this work?: print Dumper(do { delete local  @$hashref{ @$bad_keys }, $hashref} ); or this print Dumper(do { delete local  @$hashref{ @$bad_keys }; $hashref} ); My intention is to delete the elements of the local hash, pass that to Dumper and hopefully leave it untouched when Dumper returns.

my @unwanted = qw( schema log ); my %hash = (schema=>1, log=>2, aa=>3); print Dumper(delete local @hash{ @unwanted }, \%hash); print Dumper(\%hash); $VAR1 = 1; $VAR2 = 2; $VAR3 = { 'aa' => 3 }; $VAR1 = { 'aa' => 3 };
my @unwanted = qw( schema log ); my %hash = (schema=>1, log=>2, aa=>3); print Dumper(do { delete local @hash{ @unwanted }; \%hash }); print Dumper(\%hash); $VAR1 = { 'aa' => 3, 'log' => 2, 'schema' => 1 }; $VAR1 = { 'aa' => 3, 'log' => 2, 'schema' => 1 };

Replies are listed 'Best First'.
Re^4: Hash/Array slice : how to exclude items?
by hv (Prior) on Jan 24, 2023 at 23:15 UTC

    delete returns the thing(s) deleted, not the things remaining after deletion, so that idea won't fly.

    The effect of local is undone at the end of the block (scope) in which it was done, so your proposed examples cannot work - the elements have already been restored by the time Dumper() gets a look at the hash.

    If you can put the Dumper() call inside the block, then it will work:

      print do { delete local @$hashref{ @$bad_keys }; Dumper($hashref) };

    For a complete example:

    % perl -we '%a=(schema=>1,log=>2,aa=>3); use Data::Dumper; print do { delete local @a{qw{ schema log }}; Dumper(\%a) }' $VAR1 = { 'aa' => 3 }; %

      yes I was trying to return the local copy really. But as you said it gets restored.

Re^4: Hash/Array slice : how to exclude items?
by LanX (Saint) on Jan 25, 2023 at 01:44 UTC
    > 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

      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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11149848]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-19 12:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found