Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Use method/function signatures with Perl

by BrowserUk (Pope)
on Dec 06, 2004 at 04:45 UTC ( #412584=note: print w/ replies, xml ) Need Help??


in reply to Use method/function signatures with Perl

I'm not sure if this is a useful idea, but have you considered using wantarray or Want to allow dispatch on return context also?

I was in the process of trying to hand code a multi-dispatch method for a function that takes 3 args. Two of which can be either strings, or array refs, or hash refs, or globs. The third is a simple scalar.

The function applies the value or values (which can be a single scalar, or an array of scalars, the keys of a hash, or each of the lines from an open file handle) of the second argument, to each of values (a scalar, and array of scalars, or the keys of a hash, or lines from a file) of the first argument.

I want to use separate subs for each of the variations for two reasons:

  1. Having conditional code in the body of the sub to handle all these variations would horrible complicate the code.
  2. It would also slow the code by a big margin for something that needs to be fast.

I think your module would be of great value here.

However, the way the function would report it's results would (could) also depend on the context in which it is called. In a void context, it would write the results straight to STDOUT, thereby avoiding accumulating large volumes of data in memory and passing it, or a reference to it, back to the caller to write to a file.

If the first parameter is a hash ref, then the results of applying the function to a key, would be stored back into the hash as a value and a total count of results return in a scalar context, or a list of counts for the keys in a list context (maybe?).

If the first parameter is an array, a reference to an array of results would be returned in a scalar context and a list of results in a list context.

For two scalars, an array ref in a scalar context, or the results themselves in a list context.

With Want, other useful variations would be possible (I think, I only just downloaded it a coupleof days ago). I can put code in each of the subs to make this determination, but again, it complicates and slows down the code.

Any chance you might be able to incorporate caller context in the dispatch also?


Examine what is said, not who speaks.
"But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
"Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon


Comment on Re: Use method/function signatures with Perl
Re^2: Use method/function signatures with Perl
by Ovid (Cardinal) on Dec 06, 2004 at 06:01 UTC

    That's a fascinating thought, I must admit. I'll keep it in mind, though I'm unsure of the best approach for implementation. For the time being, you could use a wrapper subroutine that handles the context for you and have it call the "signified" subs.

    Cheers,
    Ovid

    New address of my CGI Course.

      No. I can't either. I was initially thinking that as your running at compile time, you could generate a sigified-without-context wrapper sub that detectes the context and dispatched to the sigified-with-context subs.

      And then replicate the user written sigified-without-context subs, to save coder effort and (human) cut&paste code reuse.

      Unfortunately, whilst entirely possible to do, it doen't buy you much as you end up with three version of the same code with different names.

      I tried to think of some way of using the source-filter nature of your module to perform some source-substitution "macro expansion" when generating the 3 variant requirements, but it may be too big a task I fear.

      In the simple case of don't do anything in a void context and return the list or a reference to it in the other two, it's easier, and perfectly efficient to make that determination at runtime.

      For the more complex case, the best idea I came up with is a a trio of pseudo-pseudo-blocks.

      VOID{ ... } SCALAR{ ... } LIST{ ... }

      When munging the subnames in the source filter, you'd also look for these. If the user's sub definition contained one or more of them, then you would generate the signified-without-context dispatcher sub. And one signified-with-context duplicate of the user's sub definition, but with the appropriate pseudo-block label, and the entirity of the other two types of pseudo-block removed. Or a fatal exception catcher for any that didn't exist.

      It apppealed for a while, but I'm not sure that any efficiency gains from the removal of the runtime conditionals would give wouldn't be outweighed by the extra level of dispatch. And whilst the pseudo-blocks would allow the user's source to be fairly clean if the decisions are simple, it could easily get messy if they are more complex.

      Finally, the extra complexity in the source filter would probably make test and validation much harder for production quality to be achieved.

      Oh well. It seemed like a good notion when the thought struck me.


      Examine what is said, not who speaks.
      "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
      "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2014-09-22 03:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (178 votes), past polls