using_perl
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | using_perl [2006/08/29 20:18] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ======Using the inbuilt embedded perl functions====== | ||
+ | |||
+ | Let me start out by saying that it is possible, and still advisable in | ||
+ | most cases to use the [[exec command|EXEC]] command to do many of the things you want | ||
+ | from an external scripting language. The external script will run as a | ||
+ | separate process which will save you performance problems and memory. | ||
+ | |||
+ | The reason you might want to use the $[[perl function|perl]]*() | ||
+ | functions are in those situations where you need data to be returned | ||
+ | from the perl script or if you need it to do something within the epic | ||
+ | environment from that script. These mechanisms are faster and much more | ||
+ | stable in these functions than trying to do the same thing with an | ||
+ | /[[exec command|exec]]. | ||
+ | |||
+ | The perl environment can be used at many levels, from being a helper | ||
+ | to your irc script to almost entirely driving your script from within | ||
+ | perl. Most perl modules are available for use from within the perl | ||
+ | environment, | ||
+ | unlikely to be useful. It is also makes it possible to alter epics | ||
+ | process environment, | ||
+ | other random system calls, which is not always a good idea. | ||
+ | |||
+ | The embedded perl script starts with a call to $[[perl | ||
+ | function|perl]](expression). When $[[perl function|perl]]() is called, | ||
+ | the perl environment is initialized and the expression is evaluated. | ||
+ | |||
+ | Typically what you want is an expression that loads a script or defines | ||
+ | subroutines for use from your epic environment with the $[[perlcall]]() | ||
+ | functions. | ||
+ | |||
+ | At this point, the $[[perlcall]]() and $[[perlxcall]]() functions can be used | ||
+ | to call whatever subroutines have been defined. $[[perlcall]](sub any text) | ||
+ | calls the perl subroutine " | ||
+ | argument. More complex calls involving Karll [[arrays]](7) are possible with | ||
+ | $[[perlxcall]](). | ||
+ | |||
+ | Three new subroutines are available from within the perl environment: | ||
+ | EPIC::cmd evaluates its arguments as irc commands, returning nothing. | ||
+ | EPIC::eval evaluates its arguments as if they were applied to /[[eval]], | ||
+ | also returning nothing. EPIC::expr evaluates its arguments as epic | ||
+ | [[expressions]](7), | ||
+ | |||
+ | The exact difference between cmd and eval is that anything passed to | ||
+ | eval is subject to Epics parsing rules while anything passed to cmd is | ||
+ | not. This is not unlike the difference between single and double quoting | ||
+ | in perl. | ||
+ | |||
+ | You can use these to " | ||
+ | going to do this with a long running script, it is highly recommended | ||
+ | that you make calls to EPIC:: | ||
+ | |||
+ | You should not call the EPIC functions from within %SIG signal handlers | ||
+ | other than $SIG{__WARN__} and $SIG{__DIE__}. Epics internals are likely | ||
+ | to be unable to handle such behavior. | ||
+ | |||
+ | From the perl environment, | ||
+ | settings can be changed via the EPIC functions: | ||
+ | |||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC::cmd ('echo $foo' | ||
+ | |EPIC::cmd ("echo $foo" | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |EPIC:: | ||
+ | |||
+ | To fully understand what is possible with EPIC::expr, you should read | ||
+ | [[Expressions]](7). Briefly, you can retrieve anything from within the | ||
+ | epic environment with it, and do many things as well. Exceptions to | ||
+ | this are covered by EPIC::cmd and EPIC::eval, which execute commands, | ||
+ | for which you should read [[Programming]](7). | ||
+ | |||
+ | =====Miscellaneous things to be aware of:===== | ||
+ | |||
+ | By default, perl warnings and errors will be yelled and are trapable | ||
+ | with the on(5) yell hook or from perl with the $SIG{__DIE__} and | ||
+ | $SIG{__WARN__} hooks. This is accomplished with EPIC::yell. This you can | ||
+ | use for your own purposes, but it's better to use EPIC::cmd "echo ...". | ||
+ | |||
+ | $[[perlcall]]() and $[[perlxcall]]() will return a zero length string if they | ||
+ | are called while the perl environment is uninitialized or if the sub is | ||
+ | undefined. You can use this from within an epic script to trigger an autoload | ||
+ | of a perl subroutine for eg. | ||
+ | |||
+ | In terms of performance, | ||
+ | overhead of switching to perlspace takes an order of magnitude longer than | ||
+ | making the same call from perlspace. To gain performance, | ||
+ | switching universes as much as possible. The EPIC::* functions all take and | ||
+ | return lists. You will probably find that combining many calls into one makes | ||
+ | them a lot faster. | ||
+ | |||
+ | While it is possible to write a script almost entirely in perl, with calls to | ||
+ | the EPIC functions, the script will need to be loaded with a call to | ||
+ | $[[perl function|perl]]() from an epic script or with a command. | ||
+ | |||
+ | The EPIC::* functions will execute within the context that called | ||
+ | $[[perl function|perl]]*() so it is possible to manipulate epic variables local to that | ||
+ | context. | ||
+ | |||
+ | While perl is quite capable of assigning any string of characters to a | ||
+ | variable, epic is not. Any perl string containing a null character will | ||
+ | be silently truncated when it is assigned to an epic variable. | ||
+ | |||
+ | Using perl for non-trivial networking is likely to be trickier than under pure | ||
+ | perl. Not only does your code have to maintain its sockets, but it has to give | ||
+ | epic enough cpu time to maintain its own. This can be done by including all of | ||
+ | epics file descriptors in a perl select() call and calling EPIC::eval "pause 1" | ||
+ | each time select returns one of them. There currently is no definitive way to | ||
+ | obtain these descriptors, | ||
+ | to server|send_to_server]] and [[on dcc raw|dcc_raw]]. | ||
+ | |||
+ | Alternatives to the above are: | ||
+ | * Use epic for networking with the raw dcc interface. | ||
+ | * Use an external script to handle the request, via the exec interface. | ||
+ | * Keep your perl networking code short and sweet. | ||
+ | |||
+ | "alias perl unless (functioncall()) {@perl($*)}" | ||
+ | command|PERL]] command. The arguments will be executed within the | ||
+ | embedded perl environment. You may also want to use this alias for | ||
+ | calling an external interpreter, | ||
+ | /[[perl command|PERL]] command. The choice is yours. | ||
using_perl.txt · Last modified: 2006/08/29 20:18 by 127.0.0.1