blazar has asked for the wisdom of the Perl Monks concerning the following question:

I must say as a premise that I'm not keen myself on indirect object notation, and I've at best seldom adopted it, if ever.

However, it occured to me a case in which for some reason it would have seemed natural for me to use it. Trimmed down to an absolute minimum suppose I have a class Foo:

# -*- Perl -*- package Foo; use strict; use warnings; sub new { bless [], shift } sub warn { shift; warn "[", __PACKAGE__, "] ", @_ } sub do_cb { my ($self, $cb)=@_; $self->$cb; } 1; __END__
Such that the do_cb method accepts and runs a callback. Now, if I use it like thus:
#!/usr/bin/perl use strict; use warnings; use Foo; my $f=Foo->new; $f->do_cb(sub { my $caller=shift; $caller->warn("no good for me\n"); }); __END__
then everything is fine. But if I try
warn $caller "no good for me\n";

instead, it doesn't work due to warn() being a builtin function. Incidentally, the latter form seems quite expressive to me in terms of message passing to the "caller" object.

So leaving aside for the moment any argument about how {risky,dangerous,error-prone,whatever} this could be (for I'm aware about them - and please do not point out I can call it "Warn" either, for I know that too), is it first of all possible, some way or another? (Especially given that in perl I can even replace most builtins with my own subs.)

UPDATE: Fixed a "minor but relevant" bug! (Thanks to Fletch.)

Replies are listed 'Best First'.
Re: Speaking of indirect object notation...
by Fletch (Bishop) on Apr 21, 2005 at 15:10 UTC

    Don't you mean $caller not caller (which is also a builtin and might be throwing things off)?

      Most definitely! Indeed my fault for the typo (should have noted from the "erroneous error message" - no pun intended!)

      However, no: that's not what is "throwing things off"...

Re: Speaking of indirect object notation...
by dragonchild (Archbishop) on Apr 21, 2005 at 15:09 UTC
    No, because how is perl supposed to guess you want caller's warn() instead of the built-in one?
      Well, you can persuade the parser to parse a builtin with your own sub, I thought there could have been a (arcane, hackery, tricky) way to persuade it to disambiguate the expression giving preference to the indirect object notation.
        . . . you can persuade the parser to parse a builtin with your own sub, . . .

        Actually, you're replacing the builtin with your sub, not "persuading the parser" to do squat. The only ways to "persuade the parser" to do what you want are

        • $caller->warn( ... )
        • my_warn $caller ( ... )

        Sorry.

Re: Speaking of indirect object notation...
by Thelonious (Scribe) on Apr 22, 2005 at 01:17 UTC
    You can replace a builtin with your own sub like so:

    *CORE::GLOBAL::glob = \&File::Glob::csh_glob;

    ...at least that's how File::Glob does it. It doesn't work with warn (and some others that I tested), though. I'm not sure why some would work and others wouldn't...

    (...anyone?)

Re: Speaking of indirect object notation...
by Anonymous Monk on Apr 21, 2005 at 16:13 UTC
    This is exactly why using the indirect object syntax should not be used. Because it will call the wrong function in cases like this.