Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

•Re: One liner to Check and undef hash elements

by merlyn (Sage)
on Apr 16, 2003 at 02:13 UTC ( [id://250758]=note: print w/replies, xml ) Need Help??


in reply to One liner to Check and undef hash elements

Problem 1:
my $hash_has_non_undef = sub { while (my ($key, $value) = each %hash) +{ return 1 if defined $value } 0 }->();
Problem 2:
@hash{keys %hash} = ();

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

Replies are listed 'Best First'.
Re: •Re: One liner to Check and undef hash elements
by crenz (Priest) on Apr 16, 2003 at 10:37 UTC

    Nice! I knew there had to be a better way. Regarding problem 1, what exactly does ->() do? I know that without it, a coderef would be returned, and with it, the result is returned. But how does it work? Does it evaluate the sub on the spot or in the moment I access $hash_has_non_undef?

      sub { ... } as an expression returns a reference to an anonymous function. ->(@list); takes a reference to an anonymous function and calls it. So what happens when you chain them is you define an anonymous function and call it on the spot, the anonymous function being lost, because you didn't save the reference anywhere.

      Makeshifts last the longest.

Re^2: One liner to Check and undef hash elements (shortcircuiting)
by Aristotle (Chancellor) on Apr 16, 2003 at 11:38 UTC

    Doh, I knew there was a single step approach for Nr.2.. it just wouldn't occur to me last night.

    I'm not sure I like your approach to the first one though - using a subref to get around the lack of control in naked blocks seems to hackish. I'm not really happy with my own alternative, either:

    my $hash_has_non_undef = do { local $_; my $found = 0; defined && ($found++, last) while (undef, $_) = each %hash; $found; };
    But without Perl 6 junctions there's not much that can be done about it if you need shortcircuiting..

    Makeshifts last the longest.

      Well, the non-sub way could look like this:
      my $hash_has_non_undef = do { my $found; until($found or not (undef, m +y $v) = each %hash) { $found = defined $v } $found };
      I mean, that's the way we had to do it in Pascal. Stupid boolean flag variables all over the place because they wouldn't let us exit blocks. {grin}

      Doh! As I'm staring at this, I realize the $v can do double duty.

      my $hash_has_non_undef = do { my $v; until($v or not (undef, $v) = eac +h %hash) { $v = defined $v } $v };
      But that's optimized for Golf, not for maintenance. Ick.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Yeah, I know.. you can at least drop a last in there and simplify the loop condition, if you use a while. Or how about a variant on until:
        my $hash_has_undef = do { local $_; 1 until defined or not (undef, $_) = each %hash; defined; };
        Traded the flag variable for a double defined test on the last value fetched from the hash.

        Makeshifts last the longest.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-03-28 23:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found