in reply to A caller() by any other name

If I understand your question correctly, you have a situation in which you call $foo->a(), which calls $bar->b(), and in the second call, you want to get $foo. Is that right?

You could, of course, pass $foo as an argument. As you correctly note, doing that "violates one, or more, OO rules & best practice(s)." I think that's also true if you could get this info from caller or some analog. That is, your desire to know this info may reveal a design problem.

You go on to say that maybe this could be a class behavior that you can add to any classes that need it. I agree this is probably a better solution, if this kind of interface is really needed at all. Something as simple as Re: Proper way to create 'globals' might do the trick too.

Replies are listed 'Best First'.
Re^2: A caller() by any other name
by Bloodnok (Vicar) on Dec 02, 2008 at 12:18 UTC
    Indeed, dead right in one :-)

    IMHO, extending (caller)[0] to return an instance (c/w a package) isn't a violation to the same degree since it would be incumbent on the called sub/method to use the information presented...the design problem, such as it is, is outlined in my OP - being the need to implement inter-class relationships (as defined in a class diagram), hence my suggested afterthought WRT a class to implement the relationship between the participating classes - thus...

    • Each participating class registers itself with the Relationship class - not knowing, or indeed needing to know, about the other class(es) in the relationship.
    • The Relationship class handles method invocations between the participating objects.

    AFAICS, Re: Proper way to create 'globals' would only work for singleton/monadic classes - it would need some work to achieve the same end for classes having multiple instances.

    A user level that continues to overstate my experience :-))
      I'm not sure if I'm just reiterating kennethk's solution in the language of lexicals-in-closures rather than globals, but couldn't you do something like:

      UPDATE: On further thought, you could even confine the messiness of those caller->caller semantics to one place by defining a function like

      sub called_by { return ( caller 1 )[0]->caller; }