http://www.perlmonks.org?node_id=157317


in reply to Re: (3): Perl 6 will make amends (was:Perl's Bad Ideas)
in thread Perl's Bad Ideas

Thanks for the enlightenment.
Satori can arrive in the most unlikely ways. But I suspect I really only brought you information. ;-)
...nice would be able to tell if you are called in a control structure or not for lazy DWIM functions
Sure. Depending on what kind of context information you're after, you'll use either caller or want (the successor to wantarray).

Replies are listed 'Best First'.
Re: Re: Re: (3): Perl 6 will make amends (was:Perl's Bad Ideas)
by shotgunefx (Parson) on Apr 07, 2002 at 22:12 UTC
    Particularly, I'd like to be able to detect if the current sub was called from within a control block.

    For example, I wrote an operator called findone which operates like grep, returning the first match and optionally the index of the match lazily.

    I know I could do this with a iterative closure but I wanted it to be like a built-in. So I saved the args for the call in a hash with a key of caller() = ref. This almost works. The problem is that if it is not called in a control block (Example 2.) it will fail after the last match as there is no context to know that we shouldn't save state. Obviously there are other ways to accomplish this, but I would think there is probably other applications of this type of context info.

    # Example: findone { coderef } @array # Example 1. WORKS while (my ($el,$index) = findone { m/good/ } @potentially_huge_array) +{ # Found match in $el do something. } # Example 2. DOESN"T WORK my @tokens = (tokens here); while ($line =<>){ chomp($line); die "$line is not a valid token" unless findone { m/^$line/ } @tok +ens; # Fails after all elements have been processed and will always fai +l from now on. }


    -Lee

    "To be civilized is to deny one's nature."
      To do this kind of context detection, the new want function would need to be able to report that a particular closure was called in the argument list of a particular subroutine.

      That is, you'd need to be able to write something like:

      sub findone (&matcher, *@list) { ... do_caching() if want.arg_of =~ ('while','until'); }

      I don't see any reason why this kind of (compile-time discernible) information shouldn't be made available, especially since creating new control structures via subroutines will likely be far more common in Perl 6.

      I'll see what Larry thinks.

        I hope so. What i did in the case of findone was use Filter::Simple (Thanks) to try and detect the usage and change it to a different function made for non-iterative calls when appropriate.

        -Lee

        "To be civilized is to deny one's nature."
        Update
        My eyes must have glazed over it when I read it the first time.
        "I'll see what Larry thinks.", is this place great or what?