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


in reply to Free-Form Delegated Behavior

I've read your post several times now and I keep coming back to the same question: How do you write code to use methods you don't know the names of?

With normal inheritance, you write the code in terms of the base class methods, and the subclass overrides (or just provides) the implementation. But the method names and parameters are known up front.

What you appear to be describing is a mechanism for constructing classes or objects at runtime and "discovering" the methods available on the fly. And your concern is how to safely invoke the methods so discovered.

My concern would be how could you ever write code to use such an object?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Free-Form Delegated Behavior
by John M. Dlugosz (Monsignor) on Apr 26, 2011 at 00:56 UTC
    Look at the synopsis for Marpa. It shows a simple grammar that triggers do_add and do_multiply actions, and supplies all the actions in a package called MyActions.

    Now suppose I want to derive from this grammar. I add a production that calls do_exponent, which is easy to do: just push it on the list of productions, or call rules again on the existing parser instance to add another rule.

    Now how do I add the implementation of do_exponent? I don't want to add it to the MyActions package, although Perl supports injecting it without altering the original source file. That's the problem I ran into with the Alpha API.

    Now if the Action methods in MyActions were already acting like true methods, using the first argument as an instance and doing more stuff with it (say, to built a tree representation of the parse), it makes sense that my new do_exponent function would also want to call the (inherited!) helpers to manipulate and prepare the tree nodes.

    Knowing the difference between public API functions and private internal guts is a general Perl problem not unique to this. You see a class, you can write code to call anything willy-nilly, since it doesn't have protection. Just don't do that! Call the documented methods for their intended purpose. In this grammar example, the Actions named in the grammar are no different than normal code written to use a class. I code calls to methods I know about, and don't code calls to "other stuff" I found from looking through the source file or the package symbol table.

    My suggestions for the Marpa API in particular don't deal with "discovery", and is no different from any other module in that you write code that uses the methods you discover only by reading the documentation.

    Extending it to "discovery", like with Catalyst that lets you write methods that will be bound to URLs and called by surfing the web, is more general and not needed by Marpa in particular. But if there was a general module that "did the callback behavior", and it supported tagging the callable actions, that would be just fine.

    Hmm, I seem to have strengthened my argument that the Actions in Marpa should be done with an object. When using Marpa, you also code a module/class of some kind yourself, and code calls to that module. It's like any other module usage, only the code that calls the entry points doesn't look like typical Perl code but is highly declarative.