in reply to How to distinct the call position of a sub?

And caller() doesn't help?
my ($package, $file, $line, $subname, $hasargs, ...) = caller();
I'd think that the combination of $package, $line, and $subname ought to be pretty specific.....

----
I Go Back to Sleep, Now.

OGB

Replies are listed 'Best First'.
Re^2: How to distinct the call position of a sub?
by Limbic~Region (Chancellor) on Nov 24, 2008 at 20:17 UTC
    Old_Gray_Bear,
    I would agree with the caveat that it would likely fail to DWIM in many situations. Assuming way too much about how LanX will use it, the following seems to work:
    #!/usr/bin/perl use strict; use warnings; { my %seen; sub iter { my ($beg, $end, $by) = @_; my $key = join '*', caller(); return $seen{$key}->() if $seen{$key}; my $pos = $beg - $by; $seen{$key} = sub { $pos += $by; if ($pos > $end) { delete $seen{$key}; return; } return $pos; }; return $seen{$key}->(); } } while (my $x = iter(1, 10, 1)) { print "$x\n"; while (my $y = iter(1, 10, 1)) { print "$x - $y\n"; } }
    Update: In some versions of perl (5.8.8 and 5.10.0 reported in the CB), an infinite loop results if you delete the print "$x\n"; line. It seems that unless there is some executable statement between the two while loops, caller reports them as happening on the same line. While I think this is a bug in perl, it also shows why this is not a good solution. Running perl -MO=Deparse doesn't seem to support why perl believes they are on the same line.

    Cheers - L~R

      Seems to be rather fragile... i.e. for me it works with Perl 5.10.0 if you leave in the print "$x\n"; (without it, I can replicate the infinite loop), but with Perl 5.8.8, the iterator returns the wrong values (with and without the print "$x\n"; — no infinite loop here, though):

Re^2: How to distinct the call position of a sub?
by LanX (Saint) on Nov 24, 2008 at 20:45 UTC
    Well ... would you publish a syntax extension with the footnote "but never use it in the same line!" ?

    And beside this, iterator are just an example for a general problem to know "which call is this".

    Think about a position sensitive function you want to call twice within a ternary operator ... "never use it in the same line?"

    And even when I publish it with this restriction, I have no means to throw an error-message if used in a wrong way.

    So if there is a general clean solution, where else should I try to ask for wisdom?
    And shouldn't I ask before implementing an imperfect solution? 8 )

    Cheers Rolf

      And beside this, iterator are just an example for a general problem to know "which call is this".

      I don't think there's a reliable solution, which is why I think any design based on having this information is flawed. What do you expect to get if you're called from string eval?

        > What do you expect to get if you're called from string eval?

        what do you expect when you call foreach from string eval?
        Well you bring a good argument against using the linenumber from caller.

        Cheers Rolf