FAQ
I'd like to be able to tell whether the current sub was called as a method.

A simple (to use) way to do this would be to make it available as a bool in the
result of caller.

confess "bad programmer, no cookie" unless (caller)[11];

There was some discussion on #p5p about how this would be done: maybe entersub
would be altered to know it was a method call, and would then pass that along.
I don't know how it would work, I just know it would be useful information.

--
rjbs

Search Discussions

  • Mark Jason Dominus at Jan 10, 2008 at 8:54 pm
    I'd like to be able to tell whether the current sub was called as a method.
    Bravo. At present, there is absolutely no way to do this. One
    problem it would solve is that there is no way for AUTOLOAD to issue
    an appropriate error message.
    A simple (to use) way to do this would be to make it available as a
    bool in the result of caller.

    confess "bad programmer, no cookie" unless (caller)[11];
    I wonder if maybe it is time to say that the last element of caller()
    will be a hashref?

    Or maybe a declaration like

    use feature 'caller-hash';

    would turns caller()'s entire return value into a hash?
  • Zefram at Jan 10, 2008 at 9:16 pm

    Mark Jason Dominus wrote:
    use feature 'caller-hash';

    would turns caller()'s entire return value into a hash?
    Smells like a different function. Leave caller() as it is, and add
    caller_hash(). No reason the two couldn't be used in the same block
    of code.

    -zefram
  • Tatsuhiko Miyagawa at Jan 10, 2008 at 9:56 pm

    On 1/10/08, Mark Jason Dominus wrote:

    Or maybe a declaration like

    use feature 'caller-hash';

    would turns caller()'s entire return value into a hash?
    What about a module to export caller() that returns a hash or an
    object, like File::stat, User::pwent or Time::Piece do.


    --
    Tatsuhiko Miyagawa
  • Tatsuhiko Miyagawa at Jan 10, 2008 at 9:59 pm

    On 1/10/08, Tatsuhiko Miyagawa wrote:
    What about a module to export caller() that returns a hash or an
    object, like File::stat, User::pwent or Time::Piece do.
    And there's already one on CPAN. Doh.
    http://search.cpan.org/~ovid/Perl6-Caller-0.04/lib/Perl6/Caller.pm

    --
    Tatsuhiko Miyagawa
  • Nicholas Clark at Jan 11, 2008 at 12:23 pm

    On Thu, Jan 10, 2008 at 01:59:34PM -0800, Tatsuhiko Miyagawa wrote:
    On 1/10/08, Tatsuhiko Miyagawa wrote:
    What about a module to export caller() that returns a hash or an
    object, like File::stat, User::pwent or Time::Piece do.
    And there's already one on CPAN. Doh.
    http://search.cpan.org/~ovid/Perl6-Caller-0.04/lib/Perl6/Caller.pm
    There are CPAN authors other than your good self.
    And they're not in the minority yet, although I'm sure that you're working
    on that. :-)

    Nicholas Clark
  • Ricardo SIGNES at Jan 11, 2008 at 2:08 am
    * Mark Jason Dominus [2008-01-10T15:53:46]
    A simple (to use) way to do this would be to make it available as a
    bool in the result of caller.

    confess "bad programmer, no cookie" unless (caller)[11];
    I wonder if maybe it is time to say that the last element of caller()
    will be a hashref?
    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like thing
    noticing that caller was being assigned to %caller. Once we're at caller()
    returning a dozen things, though... I do start to want something clearer than a
    list. I certainly don't object to some kind of core object.

    --
    rjbs
  • Chromatic at Jan 11, 2008 at 5:34 am

    On Thursday 10 January 2008 18:08:00 Ricardo SIGNES wrote:

    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like
    thing noticing that caller was being assigned to %caller. Once we're at
    caller() returning a dozen things, though... I do start to want something
    clearer than a list. I certainly don't object to some kind of core object.
    In scalar context it returns a package name. Is there any reason that,
    backwards-compatibility speaking, this couldn't be an object with overloaded
    stringification?

    -- c
  • Nicholas Clark at Jan 11, 2008 at 12:24 pm

    On Thu, Jan 10, 2008 at 09:34:00PM -0800, chromatic wrote:
    On Thursday 10 January 2008 18:08:00 Ricardo SIGNES wrote:

    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like
    thing noticing that caller was being assigned to %caller. Once we're at
    caller() returning a dozen things, though... I do start to want something
    clearer than a list. I certainly don't object to some kind of core object.
    In scalar context it returns a package name. Is there any reason that,
    backwards-compatibility speaking, this couldn't be an object with overloaded
    stringification?
    This seems like a workable solution.

    Nicholas Clark
  • Ricardo SIGNES at Jan 11, 2008 at 1:29 pm
    * chromatic [2008-01-11T00:34:00]
    On Thursday 10 January 2008 18:08:00 Ricardo SIGNES wrote:
    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like
    thing noticing that caller was being assigned to %caller. Once we're at
    caller() returning a dozen things, though... I do start to want something
    clearer than a list. I certainly don't object to some kind of core object.
    In scalar context it returns a package name. Is there any reason that,
    backwards-compatibility speaking, this couldn't be an object with overloaded
    stringification?
    I don't know, I can easily imagine:

    if (caller->isa('Some::Package')) {
    ...
    }

    ...or any other method, really. After all, the current scalar context return
    from caller is already a valid method invocant. Is it just going to magically
    redispatch all methods to the actual package, meaning that you can't tell that
    this isa Perl::Caller?

    --
    rjbs
  • Demerphq at Jan 11, 2008 at 1:35 pm

    On 11/01/2008, Ricardo SIGNES wrote:
    * chromatic [2008-01-11T00:34:00]
    On Thursday 10 January 2008 18:08:00 Ricardo SIGNES wrote:
    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like
    thing noticing that caller was being assigned to %caller. Once we're at
    caller() returning a dozen things, though... I do start to want something
    clearer than a list. I certainly don't object to some kind of core object.
    In scalar context it returns a package name. Is there any reason that,
    backwards-compatibility speaking, this couldn't be an object with overloaded
    stringification?
    I don't know, I can easily imagine:

    if (caller->isa('Some::Package')) {
    ...
    }

    ...or any other method, really. After all, the current scalar context return
    from caller is already a valid method invocant. Is it just going to magically
    redispatch all methods to the actual package, meaning that you can't tell that
    this isa Perl::Caller?
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }

    :-)

    yves

    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • Rafael Garcia-Suarez at Jan 11, 2008 at 2:06 pm

    On 11/01/2008, demerphq wrote:
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }
    You like magic vars, don't you ?

    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)
  • Demerphq at Jan 11, 2008 at 2:09 pm

    On 11/01/2008, Rafael Garcia-Suarez wrote:
    On 11/01/2008, demerphq wrote:
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }
    You like magic vars, don't you ?

    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)
    Yes i do like magic vars. For stuff like this anyway.

    And its not so weird. 'this' in C++ and many other languages is
    essentially a magic var.

    Yves

    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • Abigail at Jan 11, 2008 at 2:12 pm

    On Fri, Jan 11, 2008 at 03:06:44PM +0100, Rafael Garcia-Suarez wrote:
    On 11/01/2008, demerphq wrote:
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }
    You like magic vars, don't you ?

    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)

    If, instead of using undef for sub calls, ${^INVOCANT} would be a code
    ref to itself for sub calls, one would be able to write recursive
    anonymous subroutines:

    my $fac = sub {$_ [0] <= 2 ? $_ [0] : $_ [0] * &${^INVOCANT} ($_ [0] - 1)};

    A different magical variable would do as well, of course.


    Abigail
  • Demerphq at Jan 11, 2008 at 2:16 pm

    On 11/01/2008, Abigail wrote:
    On Fri, Jan 11, 2008 at 03:06:44PM +0100, Rafael Garcia-Suarez wrote:
    On 11/01/2008, demerphq wrote:
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }
    You like magic vars, don't you ?

    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)

    If, instead of using undef for sub calls, ${^INVOCANT} would be a code
    ref to itself for sub calls, one would be able to write recursive
    anonymous subroutines:

    my $fac = sub {$_ [0] <= 2 ? $_ [0] : $_ [0] * &${^INVOCANT} ($_ [0] - 1)};

    A different magical variable would do as well, of course.
    This is what the $^ROUTINE var from Sub::Routine does and which ive
    wanted for ages. :-)

    The only problem i would have with merging $^ROUTINE and $^INVOCANT is
    how would you tell whether you are in a recursive routine or in a
    method of an object which happens to be a blessed sub.

    Yves

    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • Rafael Garcia-Suarez at Jan 11, 2008 at 2:24 pm

    On 11/01/2008, demerphq wrote:
    If, instead of using undef for sub calls, ${^INVOCANT} would be a code
    ref to itself for sub calls, one would be able to write recursive
    anonymous subroutines:

    my $fac = sub {$_ [0] <= 2 ? $_ [0] : $_ [0] * &${^INVOCANT} ($_ [0] - 1)};

    A different magical variable would do as well, of course.
    This is what the $^ROUTINE var from Sub::Routine does and which ive
    wanted for ages. :-)
    Sub::Current, actually.
    The only problem i would have with merging $^ROUTINE and $^INVOCANT is
    how would you tell whether you are in a recursive routine or in a
    method of an object which happens to be a blessed sub.
    Not mentioning references blessed into the CODE package :)
  • Demerphq at Jan 11, 2008 at 2:27 pm

    On 11/01/2008, Rafael Garcia-Suarez wrote:
    On 11/01/2008, demerphq wrote:
    If, instead of using undef for sub calls, ${^INVOCANT} would be a code
    ref to itself for sub calls, one would be able to write recursive
    anonymous subroutines:

    my $fac = sub {$_ [0] <= 2 ? $_ [0] : $_ [0] * &${^INVOCANT} ($_ [0] - 1)};

    A different magical variable would do as well, of course.
    This is what the $^ROUTINE var from Sub::Routine does and which ive
    wanted for ages. :-)
    Sub::Current, actually.
    The only problem i would have with merging $^ROUTINE and $^INVOCANT is
    how would you tell whether you are in a recursive routine or in a
    method of an object which happens to be a blessed sub.
    Not mentioning references blessed into the CODE package :)
    But that wouldnt fool anybody that uses S::U::reftype()

    Which btw should be changed or complemented so that it doesnt return undef.

    Its really annoying that you end up calling sv_reftype() twice when you do

    if (ref $x and reftype $x eq $type)

    much nicer if you could just say

    if (reftype $x eq $type)

    Yves


    --
    perl -Mre=debug -e "/just|another|perl|hacker/"
  • Ricardo SIGNES at Jan 11, 2008 at 3:29 pm
    * Rafael Garcia-Suarez [2008-01-11T09:06:44]
    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)
    Then the builtin 'self' (enabled by feature 'self') will return ${^INVOCANT},
    dying if it is undef.

    sub this_is_a_method {
    return self->x * self->y
    }

    Now do we still need a 'method' keyword?

    --
    rjbs
  • Bo Lindbergh at Jan 11, 2008 at 7:29 pm
    In article <b77c1dce0801110606j4897ac5eqb41c8f88584a77ba@mail.gmail.com>,
    rgarciasuarez@gmail.com ("Rafael Garcia-Suarez") wrote:
    if (${^INVOCANT}) { ... }

    ${^INVOCANT} being either $self (for instance methods) or the class
    name (for class methods). (or undef for sub calls)
    And what should it be for indirect method calls
    when the method happens to be a sub ref?

    EXAMPLE {
    use Data::Dumper;

    my $method=sub {
    print Dumper(@_),"\n";
    };

    Data::Dumper->$method(1);
    (1+1)->$method(3);
    [4]->$method(5);
    undef->$method(6);
    }


    /Bo Lindbergh
  • Ricardo SIGNES at Jan 11, 2008 at 7:46 pm
    * Bo Lindbergh [2008-01-11T14:29:01]
    And what should it be for indirect method calls
    when the method happens to be a sub ref?

    EXAMPLE {
    use Data::Dumper;

    my $method=sub {
    print Dumper(@_),"\n";
    };

    Data::Dumper->$method(1);
    (1+1)->$method(3);
    [4]->$method(5);
    undef->$method(6);
    }
    In my opinion, none of those is a method call. If method dispatch is not
    involved, it is not a method call.

    --
    rjbs
  • Rafael Garcia-Suarez at Jan 12, 2008 at 10:14 am

    On 11/01/2008, Ricardo SIGNES wrote:
    * Bo Lindbergh [2008-01-11T14:29:01]
    And what should it be for indirect method calls
    when the method happens to be a sub ref?

    EXAMPLE {
    use Data::Dumper;

    my $method=sub {
    print Dumper(@_),"\n";
    };

    Data::Dumper->$method(1);
    (1+1)->$method(3);
    [4]->$method(5);
    undef->$method(6);
    }
    In my opinion, none of those is a method call. If method dispatch is not
    involved, it is not a method call.
    In my opinion, they are. First, because perl uses method dispatch:

    $ bleadperl -MO=Concise -e '[]->$foo()'
    9 <@> leave[1 ref] vKP/REFC ->(end)
    1 <0> enter ->2
    2 <;> nextstate(main 1 -e:1) v:{ ->3
    8 <1> entersub[t1] vKS/TARG ->9
    3 <0> pushmark s ->4
    5 <@> anonlist sKM* ->6
    4 <0> pushmark s ->5
    7 <1> method K/1 ->8
    - <1> ex-rv2sv sK/1 ->7
    6 <$> gvsv(*foo) s ->7

    Secondly, because we're on the fringe of autoboxing here.
    BTW, noone already made a proposal on autoboxing for the core ?
  • Chromatic at Jan 12, 2008 at 10:22 am

    On Saturday 12 January 2008 02:14:49 Rafael Garcia-Suarez wrote:

    BTW, noone already made a proposal on autoboxing for the core ?
    Seconded.

    -- c
  • Jesse Vincent at Jan 12, 2008 at 9:40 pm

    chromatic wrote:
    On Saturday 12 January 2008 02:14:49 Rafael Garcia-Suarez wrote:

    BTW, noone already made a proposal on autoboxing for the core ?
    Seconded.
    Thirded. I prodded nick on IRC, but it was before the 5.12 wishlist got
    into full swing.

    So. What's not-yet-right about the interface that chocolateboy's current
    autobox on cpan exports?


    -j
  • Michael G Schwern at Jan 13, 2008 at 1:46 am

    Jesse Vincent wrote:
    chromatic wrote:
    On Saturday 12 January 2008 02:14:49 Rafael Garcia-Suarez wrote:

    BTW, noone already made a proposal on autoboxing for the core ?
    Seconded.
    Thirded. I prodded nick on IRC, but it was before the 5.12 wishlist got
    into full swing.
    Fourthed.

    So. What's not-yet-right about the interface that chocolateboy's current
    autobox on cpan exports?
    For the basic mechanics it's good and performant.

    What really makes it interesting is autobox::Core, autoboxing for the built in
    functions, and that's where the fun bikeshed painting will happen.


    --
    31. Not allowed to let sock puppets take responsibility for any of my
    actions.
    -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army
    http://skippyslist.com/?page_id=3
  • Nicholas Clark at Jan 14, 2008 at 10:56 am

    On Sat, Jan 12, 2008 at 10:28:28AM -0800, Jesse Vincent wrote:
    chromatic wrote:
    On Saturday 12 January 2008 02:14:49 Rafael Garcia-Suarez wrote:

    BTW, noone already made a proposal on autoboxing for the core ?
    Seconded.
    Thirded. I prodded nick on IRC, but it was before the 5.12 wishlist got
    into full swing.
    IIRC it was before 5.10 was out. If so, I filtered it away as a distraction
    from the important task.
    So. What's not-yet-right about the interface that chocolateboy's current
    autobox on cpan exports?
    I'm not the right person to answer that. I've never felt the need for
    autoboxing.

    I look at many of these proposals and think "yes, sweet. But who is going to
    get the corner cases fixed? And who is going to maintain it next year?"

    Not *exactly* the same failure mode, but see given/when as an example of
    something that went wrong because it wasn't being maintained.


    Also, right now, I'm happily reading a lot of these threads and then deleting
    them. Once the talk dies down, please don't be surprised if nothing happens,
    because if the people with the ideas don't intersect with the people who
    actually do stuff, then nothing will get added. What you pay is what you get.

    Nicholas Clark
  • Nicholas Clark at Jan 14, 2008 at 10:59 am

    On Mon, Jan 14, 2008 at 10:55:51AM +0000, Nicholas Clark wrote:

    Also, right now, I'm happily reading a lot of these threads and then deleting
    Actually, to be more accurate, I'm happily reading these threads at my
    leisure at lower priority than most other messages, so unless you have
    access to the status bits of my mailbox it's not viable to infer whether
    I've read anything yet. (And even if you have, I might sometimes mark
    messages I've read as "New" just to confuse you)

    Nicholas Clark
  • David Landgren at Jan 14, 2008 at 12:20 pm

    Nicholas Clark wrote:
    On Mon, Jan 14, 2008 at 10:55:51AM +0000, Nicholas Clark wrote:

    Also, right now, I'm happily reading a lot of these threads and then deleting
    Actually, to be more accurate, I'm happily reading these threads at my
    leisure at lower priority than most other messages, so unless you have
    access to the status bits of my mailbox it's not viable to infer whether
    I've read anything yet. (And even if you have, I might sometimes mark
    messages I've read as "New" just to confuse you)
    Ah right, so that's why :)
  • Nicholas Clark at Jan 16, 2008 at 2:04 pm

    On Mon, Jan 14, 2008 at 10:55:51AM +0000, Nicholas Clark wrote:

    Also, right now, I'm happily reading a lot of these threads and then deleting
    them. Once the talk dies down, please don't be surprised if nothing happens,
    because if the people with the ideas don't intersect with the people who
    actually do stuff, then nothing will get added. What you pay is what you get.
    In conversation in real life, I said something that I feel is worth repeating:

    Some people are coming up with good suggestions about what they would like to
    see, but if it were suggested that they might want to cook up a patch to
    implement it, would argue that they don't know the core code well enough to
    do so, and stop there.

    This is wrong because this is defeatist.

    Take the counter example of Brandon L Black, who wanted C3 method resolution
    in core. Instead of assuming that someone else would do it, he bit the bullet
    and worked out how to implement it himself. And it's in.

    This list is happy to answer technical questions asked sensibly. (if anyone
    knows the answer - which was actually a problem in the case of MRO)
    One is far more likely to get an answer to a technical question when working
    on a patch, than someone volunteering to write the entire patch.

    Nicholas Clark
  • Joshua ben Jore at Jan 13, 2008 at 1:19 am

    On 1/11/08, demerphq wrote:
    On 11/01/2008, Ricardo SIGNES wrote:
    * chromatic [2008-01-11T00:34:00]
    On Thursday 10 January 2008 18:08:00 Ricardo SIGNES wrote:
    ...or /something/. I don't mind (caller)[-1] being a hashref, I don't mind
    having to call stack_info. I don't even mind some sort of Want.pm-like
    thing noticing that caller was being assigned to %caller. Once we're at
    caller() returning a dozen things, though... I do start to want something
    clearer than a list. I certainly don't object to some kind of core object.
    In scalar context it returns a package name. Is there any reason that,
    backwards-compatibility speaking, this couldn't be an object with overloaded
    stringification?
    I don't know, I can easily imagine:

    if (caller->isa('Some::Package')) {
    ...
    }

    ...or any other method, really. After all, the current scalar context return
    from caller is already a valid method invocant. Is it just going to magically
    redispatch all methods to the actual package, meaning that you can't tell that
    this isa Perl::Caller?
    IMO we could forget caller and use a magic var.

    if ($^IN_METHOD) {

    }
    No, I do not think this can be a magic var. How would I be able to
    something higher in my call stack whether it was called as a method?

    Also, I'd like to mention that ( caller )[-1] already returns a hash
    reference for 5.10. That is the lexical %^H info that Nick worked on
    last year. It is probably ok for scalar( caller ) to return an
    overloaded object but gosh... that's a lot of magic to quickly ask
    for. If there's a less magical and equally good solution I'd prefer
    having less magic.

    Josh
  • Chromatic at Jan 13, 2008 at 1:26 am

    On Saturday 12 January 2008 17:19:38 Joshua ben Jore wrote:

    Also, I'd like to mention that ( caller )[-1] already returns a hash
    reference for 5.10. That is the lexical %^H info that Nick worked on
    last year. It is probably ok for scalar( caller ) to return an
    overloaded object but gosh... that's a lot of magic to quickly ask
    for. If there's a less magical and equally good solution I'd prefer
    having less magic.
    There's a point at which cramming yet another difficult to read special case
    idiom into the Jenga tower which is Perl 5's introspection interface might be
    one ugly special case too many. That point just might be one step before:

    croak "Not a method, you naughty hacker"
    unless (caller)[-1]{CALLED_AS_METHOD};

    Things *could* get prettier over time.

    -- c
  • Ovid at Jan 11, 2008 at 5:19 pm

    --- chromatic wrote:

    In scalar context it returns a package name. Is there any reason
    that,
    backwards-compatibility speaking, this couldn't be an object with
    overloaded stringification?
    That's what my Perl6::Caller does and it turns out to be very useful.
    I hate trying to remember all of those indices.

    (Note that Perl6:: turned out to be an awful namespace since I just
    don't have enough information available to do everything that Perl 6's
    caller can do)

    Cheers,
    Ovid
  • Demerphq at Jan 11, 2008 at 1:15 pm

    On 10/01/2008, Ricardo SIGNES wrote:
    I'd like to be able to tell whether the current sub was called as a method.

    A simple (to use) way to do this would be to make it available as a bool in the
    result of caller.

    confess "bad programmer, no cookie" unless (caller)[11];

    There was some discussion on #p5p about how this would be done: maybe entersub
    would be altered to know it was a method call, and would then pass that along.
    I don't know how it would work, I just know it would be useful information.
    Damn straight. Anyone who has looked at the CGI code for html
    generation can attest to how useful this would be.

    Yves

    --
    perl -Mre=debug -e "/just|another|perl|hacker/"

Related Discussions

People

Translate

site design / logo © 2022 Grokbase