Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^2: Runtime introspection: What good is it?

by BrowserUk (Patriarch)
on Jul 12, 2008 at 08:53 UTC ( [id://697188]=note: print w/replies, xml ) Need Help??


in reply to Re: Runtime introspection: What good is it?
in thread Runtime introspection: What good is it?

  1. JIT.

    I'm going to reject JIT as a counter argument to my premise on the basis that:

    • If you do what JIT does at compile-time, it isn't Just In Time.

      Java bytecode is frequently compiled on a different platform to where it is run. It's not practical to translate to machine code for an unknown (number of) target platform(s).

    • What JIT does is not under the control of the (application) programmer.

      Whilst it is possible to adjust one's application programmming style to gain (more) benefit from JIT on a specific platform, and a particular implementation of the runtime on that platform, generically, JIT is beyond the control of the application programmer.

  2. ... so I leave the decision as to whether to call the method to run time where I check that the method exists by calling can, and then do one thing if it does and another if it doesn't.

    This is the 'plug-in' scenario.

    You could also do:

    sub Another::Module::particularMethod { my $o = shift; ... eval{ $o->method( ... ); } if( $@ =~ q[^Can't locate object method "method"] ) { do{ oneThing() }; } else { do{ anotherThing() }; } ... }

    Still a run-time decision. But, it can be done this way in any language that supports exceptions. No need for the inclusion of RTTI tables, or picking apart the bytecode.

    Is there any advantage to doing it this way?

    I think yes. Just because a class has a method named X, doesn't mean that X is what you think it is.

    1. That it takes the same number of parameters as you're expecting.
    2. Or the same types of parameters you're expecting.

      With some reflection APIs (eg. Java), you can discover both of these. At a considerable cost of decompiling the byte code at run-time. And at the further considerable cost of programming the logic in your code, to iterate the known public methods, with the particular name you're interested in and then check the number, and types of the parameters they expect, and the type they return.

      But even then, having done all of that discovery, you still don't know whether it:

    3. Will actually implement the same semantics as you want it to.

    Even after you've been through the laborious process of run-time discovery, when you (or whomever) eventually gets around to invoking the method, it may still raise an exception--either an 'expected' one due to bad input, or an unexpected one due to it's semantic being entirely different to what you are hoping for. Ie. Instead of calculating some statistics, it trying to wipe your harddrive.

    So, when you eventually do get around to calling the method, you're going to have to wrap the call in an exception handler anyway. So why not skip all the slow, laborious and run-time costly discovery, and just try invoking it?

    Simpler (less), clearer (it worked or it didn't; rather than: it might work(or not), it still might work(or not); it still might work(or not); it worked(or not)) code.

    Same final effect.


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^3: Runtime introspection: What good is it?
by tilly (Archbishop) on Jul 12, 2008 at 15:35 UTC
    I'm going to reject your rejection of JIT on the basis of the fact that there are things you can do with JIT that you simply cannot do at compile time. And furthermore while it is true that what changing what JIT does is beyond the control of the programmer, deliberately taking advantage of its full capabilities is not.

    A runtime type check followed by a runtime branching operation is exactly the kind of code that JIT can optimize away if you have a good JIT system.

    However I reiterate that JIT is a red herring in the case of languages like Perl that don't have it.

    Going to your exception solution, that solution has a major drawback. There are lots of possible reasons why there could be an exception, and your code has swallowed most of them. Easily fixable, granted, but not without adding more code and obscuring what is going on. And it is easy for a programmer to forget that they need to do that - I've seen many forget exactly that, including you just now.

    Not to mention the fact that if Perl made a minor change to its error message, then your code would break. Not that Perl is likely to do that, but they haven't promised they won't, and they have documented how UNIVERSAL::can works.

    Furthermore your criticisms strike me as unrealistic. If I define a plugin API, I expect to have things passed into it that are designed to be plugins. Yes, it is possible (but unlikely if you use descriptive method names, which I try to) that some random module might implement methods named the same as what I expect in my plugins. But if so then it still doesn't matter because no sane programmer is going to be passing it into my module as a plugin. (I can't solve the problem of insane programmers, and I refuse to try.)

    Thus trying to use something that isn't a plugin as a plugin is not a problem that I'm going to waste code protecting against.

    Now we have the problem of dealing with a badly designed plugin that doesn't do what it is supposed to do. Before you even consider doing that, you need to understand your problem domain. My problem domain is that I am writing plugins for use in my own module. If the plugin doesn't do what it is supposed to, that is a bug that I will fix. There is, therefore, no need for me to protect against that case. The same would apply for many of us.

    A problem domain that more closely mirrors what you're saying is one where you're writing a popular application which random third parties will add plugins to. But even there you can defend the position that it is the responsibility of the plugin author to make sure they follow your API, and not yours to code against the possibility that they didn't.

        How is it cavalier to be extremely clear on who is responsible for what in your code? When you code in one place is trying to second guess code in another that it can't control, that just leads to mess and no safety. That mess can cause confusion and real errors (such as the improper ignoring and swallowing of error messages in your code snippet).

        My opinion is if you have a plugin system you have two sane options. The first is to trust that the plugin is coded properly. That will be the best option within most corporate code bases. The second is to build an explicit controlled security environment (eg a sandbox) and make sure the plugin in that environment. That is a lot of work and adds a lot of complexity but is sometimes necessary. However if you go that route, don't do it halfway.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://697188]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-24 06:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found