User Tools

Site Tools


perlxcall

# $EPIC: perlxcall.txt,v 1.5 2007/03/02 02:32:04 jnelson Exp $

Synopsis:

$perlcall(<subroutine> [<text>])
$perlxcall(<subroutine> [<array-in> [<array-out> [<index> [<text>]]]])

Technical:

The <subroutine>, <array-in>, and <array-out> arguments are dwords which is different from most function arguments.

These functions call a given subroutine in the embedded perl interpreter and return the subroutines return value.

  • <subroutine> is the name of a subroutine in perlspace to call.
  • If <text> is given, it forms the first argument to the sub.
  • If <array-in> is given, the entire contents of the named Karll Array are additional arguments, one item per argument.
  • If <array-out> is given, it will be taken as:
    • A cue to call the given subroutine in array context instead of scalar context. Read on..
    • The name of a Karll Array into which the returned list will be dumped.
  • If <index> is given, it is the position in <array-out> at which the returned list will be added.
    • The default value is 0.
    • Negative values refer backwards from the end of the Karll Array. -1 will append to the list, -3 overwrites the last two values, etc.
    • If you actually want $perlxcall() to make the call in array context, then you must make sure that <index> is valid for <array-in>.
      • It is valid if $setitem(6) would succeed with <array-in> and <item> (or the ones compliment of <item>) as arguments.
      • Values of 0 and -1 are always valid.
  • If <array-out> and <index> are valid, the perl sub will be called in array context, the returned array will be dumped into <array-out> starting at <index> and the number of elements in the array will be returned.
  • Otherwise, it will be called in scalar context and the scalar value of the value returned will be returned.
  • <array-out> may be lengthened to accommodate extra return values, but it will never be shortened.
  • <array-in> and <array-out> may refer to the same array.

That was the excruciatingly correct way to describe these functions. The following description of $perlcall() may be better.

$perlcall() calls the sub in scalar context with one argument, text, or no arguments, if no text is present, returning the scalar value (perl term) of the value the sub returns.

Practical:

These functions are much faster and less dangerous than $perl(6) since the perl interpreter does not have to parse and/or compile the input. The downside is that you have to define or load the subroutine with a call to $perl(6) before they can be used.

$perlxcall() is useful as a prime mover of data between the perl and epic environments, and in situations where one line of code has too many or too few consequences to handle at once. In reality, it is unlikely that you will ever need to make use of all the arguments.

You can't use these functions to call primitive perl functions.

Returns:

Nothing will be returned if the perl interpreter hasn't been started with a call to $perl(6) or if an error occurred. Otherwise, the returned scalar (in scalar context), or the number of items added to the specified array (in list context) are returned.

If the perl sub returns an array when it should return a sub, that is, if it ignored wantarray, the number of items in the array will be returned, and the array will be discarded.

Examples:

Assume the following (somewhat dangerous) perl sub has been defined:

# Execute all arguments as shell commands, returning one output line
# per call in scalar context, or all at once in array context. Since
# a local @return always overshadows a global one in perl, you can
# call this sub in any sequence and it will still work as described.
sub system {
    local @return if wantarray;   # @return is global otherwise.
    for (@_) {push @return,`$_`}  # Execute all arguments.
    return wantarray ? @return : shift @return ;
}

Then, the following will work thusly:

$perlcall(system ls)  Returns the first line of ls output.
                      Repeated calls will add more data to the
                      return list, but won't be returned until the
                      output from the first one is emptied out.
$perlcall(system)     Returns the next line of ls output.  No
                      commands are actually run.
@delarray(in)         You want to be careful..  :-)
$perlxcall(system in out -1 ls)
                      Dumps the output to out all at once.  out
                      is now a running log of the shell commands.
                      Repeated calls will add to this log.  These
                      can be accessed with __getitem__(6).  See
                      [[Arrays]](7)

You could then msg(1) or notice(1) somebody with the output of these functions at a leisurely rate which will not get you flooded off the server.

Of course, you should never ever ever call this particular sub with text received from the network. There are better ways to do these things too, so you probably shouldn't have it defined, however, this does serve as a useful example.

perlxcall.txt · Last modified: 2007/03/02 02:32 (external edit)