| Inline-SLang documentation | view source | Contained in the Inline-SLang distribution. |
Inline::SLang - Write Perl subroutines in S-Lang.
use Inline SLang;
print "9 + 16 = ", add(9,16), "\n";
print "9 - 16 = ", subtract(9,16), "\n";
print JAxH('Inline'), "\n";
__END__
__SLang__
define add (a,b) { return a + b; }
define subtract (a,b) { return a - b; }
define JAxH () {
variable type = ();
return sprintf( "Just Another %S Hacker!", type );
}
The Inline::SLang module lets you write Perl subroutines in S-Lang.
It dynamically translates the parameters and return values into
native data types for both languages (or into Perl classes that are
used to represent
S-Lang types with no direct translation to Perl).
This allows you to write a Perl script and take advantage of S-Lang
whenever you wish: perhaps there is a S-Lang module that you
wish to use, or you want to take advantage of a S-Lang function
that you have written.
The module sets up an in-process S-Lang interpreter, runs your code, and then examines the interpreter's symbol table, looking for things to bind to Perl. The process of interrogating the S-Lang interpreter only occurs the first time you run your S-Lang code. The namespaces are cached, and subsequent calls use the cached version (which is hidden in the _Inline directory; see the Inline documentation for details of how the code is cached). Of course, your S-Lang code must still be run every time your run the Perl script -- but Inline::S-Lang already knows the results of running it.
From the S-Lang library home page at http://www.s-lang.org/
S-Lang is a multi-platform programmer's library designed to allow a developer to create robust multi-platform software. It provides facilities required by interactive applications such as display/screen management, keyboard input, keymaps, and so on. The most exciting feature of the library is the slang interpreter that may be easily embedded into a program to make it extensible.
For our purposes it is the S-Lang interpreter that we are interested in. See the Term::Slang module (on CPAN) if you want an interface to the terminal library provided by S-Lang.
Using Inline::SLang will seem very similar to using any other Inline language, thanks to Inline's consistent look and feel.
This section will explain the different ways to use Inline::SLang.
Further details on configuring the behaviour of Inline::SLang
can be found in Inline::SLang::Config.
For more details on Inline, see Inline or
perldoc Inline.
Using functions defined in S-Lang is just like using Perl subroutines. You just supply the source code to Inline::SLang - see the Inline manual for the various ways of doing this - and then use them in your Perl code. For example:
# set up a S-Lang function
use Inline SLang => <<'END';
define doit() { vmessage("Printing from S-Lang"); }
END
# now call the S-Lang function from Perl
doit;
By default all S-Lang functions - other than S-Lang intrinsic
functions (the functions defined by the S-Lang interpreter,
such as array_map() and assoc_get_keys()) - in the
default namespace ("Global") are bound to Perl. The
Perl functions are available in the main package.
The BIND_NS configuration option can be used to
change the list of S-Lang namespaces bound to Perl.
If you have need of an intrinsic S-Lang function then
you can either write a wrapper routine or use the
BIND_SLFUNCS option.
See Inline::SLang::Config for more details.
Note that there are no checks that a S-Lang symbol,
when mapped to Perl, does not clobber an existing value
(or is a Perl built-in function so can not be over-ridden).
So beware when you define a S-Lang function called
open()!
If you have a S-Lang module that you want to use directly
from Perl, it's as easy as the following (assuming the
module is importable and called funkymodule):
use Inline 'SLang' => 'import("funkymodule");';
and then you can start using the functions defined
by the module. You use a similar technique if you have
a file containing S-Lang code that can be loaded using
require or evalfile: e.g.
use Inline 'SLang' => 'require("funkypackage");';
The use of the require() function is only possible if
your S-Lang installation includes the slsh interpreter
and ancillary files (which is true if you use
CIAO 3.2).
We do not bind any S-Lang variables to Perl.
To access variables you have to write S-Lang routines
that read/write the variable, as shown by the
get_foobar() and set_foobar() routines below:
variable foobar = "a string";
define get_foobar() { return foobar; }
define set_foobar(x) { foobar = x; }
Inline::S-Lang attempts to seamlessly convert between Perl and S-Lang data types. For "simple" types - for example strings - where there is a direct match between S-Lang and Perl, the conversion is not noticeable. For more complicated types - such as complex numbers - S-Lang variables are converted to Perl objects. Where possible a perl-like interface is retained. See Inline::SLang::Types for more information on how the various data types are supported.
The module currently requires that yor S-Lang library has been compiled with support for both floating-point and complex numbers.
The module provides several utility functions which are
discussed below. By default they are only available
using fully-qualified names - e.g. Inline::SLang::sl_eval() -
although the EXPORT
configuration option (EXPORT in Inline::SLang::Config)
can be used to change this.
$sl = Inline::SLang::sl_array( $aref ); $sl = Inline::SLang::sl_array( $aref, $adims ); $sl = Inline::SLang::sl_array( $aref, $atype ); $sl = Inline::SLang::sl_array( $aref, $adims, $atype );
This is a wrapper around the Array_Type constructor
and is intended to make it easy to ensure that a Perl array
reference is converted into a S-Lang array of the correct
type, dimensionality, and size.
The data is stored in $aref, a Perl array reference. If
no other parameters are supplied then the array dimensions,
size, and type are guessed from $aref. Since Perl has such a
flexible type system the routine can sometimes make a surprising
choice for the data type of the array, so it may well be worth
supplying the array type as $atype - which can be either
a string containing the name of the S-Lang datatype, such as
"Int_Type", or a DataType_Type object.
If you know the array dimensions then it's probably faster
to supply them as the $adims argument, which should
be an array reference.
Note that there is limited error checking in this routine:
if $aref is a 2x3 array but you send in $adims as
[3,2] - or [24] say - then expect
weird behaviour (at the very least).
use Inline 'SLang' => Config => EXPORT => [ "sl_array" ]; use Inline 'SLang'; ... some_slang_func( sl_array([[1.0,0.0],[0.0,1.0]],"Double_Type") );
For numeric types I expect most people to use piddles. This routine is more useful for arrays of non-numeric data types.
$val = Inline::SLang::sl_array2perl(); $val = Inline::SLang::sl_array2perl( $newval );
Sets/Gets the current status of the "how do we convert a S-Lang array into Perl" flag. Returns the status.
We list the possible values of the flag below.
For further details on array support in Inline::SLang
see Inline::SLang::Array.
If PDL support was not compiled in to the module then the flag can either be 0 or 1, where
All arrays are converted to a Perl array reference.
All arrays are converted to a Perl Array_Type object
If PDL support is available then there are four options:
All arrays are converted to a Perl array reference.
All arrays are converted to a Perl Array_Type object
Numeric arrays are converted to piddles and non-numeric arrays are converted to a Perl array reference.
Numeric arrays are converted to piddles and
non-numeric arrays are converted to a Perl Array_Type object.
[ retval(s) = ] Inline::SLang::sl_eval( $str );
This function evaluates the supplied S-Lang code (in $str)
and converts any return values to Perl.
In general this will not be needed,
since you can always call S-Lang's eval() function
via a wrapper function (or by binding it to a different
function name in Perl). One approach is shown in the last
example below.
One time it can come in useful is to access a S-Lang variable (either to set its value or store its value in a Perl variable).
If $str does not end with a ";" then one will be added before the
code is evaluated by S-Lang.
# get the version of the S-Lang library
my $sl_ver = Inline::SLang::sl_eval( "_slang_version" );
# set a variable in S-Lang scope (assuming this_var exists in
# S-Lang scope)
Inline::SLang::sl_eval( "this_var = 23.5" );
# evaluate arbitrary S-Lang code
my $foo = Inline::SLang::sl_eval("23+4");
print "S-Lang thinks 23+4 is $foo\n";
A more flexible solution is to write a S-lang wrapper around
the S-Lang eval() function (perhaps this functionality should be moved
into sl_eval?):
% Call as myeval( "slang code" [, var1, var2, ... ] );
% where varX are variables that placed onto the S-Lang
% stack before calling the S-Lang code
define myeval() {
% pop off the slang code from the stack, leave the rest there
variable slcode;
if ( _NARGS > 1 ) {
_stk_reverse(_NARGS);
slcode = ();
_stk_reverse(_NARGS-1);
}
else
slcode = ();
eval( slcode );
}
$flag = Inline::SLang::sl_have_pdl();
Returns 1 if the module was compiled with support
for PDL (PDL::Intro), and 0 otherwise.
Inline::SLang::sl_setup_as_slsh();
This routine sets up the S-Lang interpreter to use the
same paths as the slsh interpreter from the S-Lang
distribution. It is called by the module when the
SETUP configuration option is set to slsh,
which is the default value. It is very unlikely that a user
will have a need to call this routine directly.
$counter = Inline::SLang::sl_setup_called();
Returns the number of times the sl_setup_slsh()
function has been called. In most cases this will
return 1 if the SETUP configuration option was
set to slsh - the default value - and 0 otherwise.
$type = Inline::SLang::sl_typeof( $var );
Returns the S-Lang type of the data stored in the Perl
variable $var. This should be more efficient than
using S-Lang's typeof() command since it does not
require the conversion of the whole variable to S-Lang
(normally not a big issue but it can be if $var contains
a large array or a complicated structure).
The return value is an object of the DataType_Type
class; see PDL::Types (PDL::Types) for more information
on how S-Lang variables are represented in Perl.
my $foo = some_slang_function(); my $type = Inline::SLang::sl_typeof($foo); print "The function returned a $type variable\n";
Note that all objects used to represent S-Lang data types
- other than Math::Complex objects - have a typeof()
method which can be used to find the type of the object.
$ver = Inline::SLang::sl_version();
Returns, as a string, the version of S-Lang
against which the module was compiled, with a format
of "a.b.c". You can use sl_eval("_slang_version_string")
to find out what version of the library
you are using.
The module will refuse to build if there is an error in the S-Lang
code compiled when your program is first run. If an error occurs
in the S-Lang interpreter - such as calling a function that expects
an argument with none - then the S-Lang error is transformed into
a Perl error (as a call to croak) and the S-Lang interpreter
is restarted.
This means that these
errors can be handled by using Perl's eval statement.
For example, the code
use strict;
use Inline 'SLang';
# Call the S-Lang function
#
my $ans;
eval { $ans = mydiv (0.0); };
print "The S-Lang error was:\n$@\n";
# Evaluate S-Lang code directly
#
eval { Inline::SLang::sl_eval( "10.0/0.0;" ); };
print "The S-Lang error was:\n$@\n";
__END__
__SLang__
define mydiv(y) { return 10.0 / y; }
(which can be found in the distribution as examples/trap_errors.pl) produces the following output:
The S-Lang error was: S-Lang Error: Divide by zero: Error while executing mydiv The S-Lang error was: S-Lang Error: Divide by zero: called from line 1, file: ***string***
The S-Lang interpreter can now be initialised in a similar manner to
that used in the slsh interpreter from the S-Lang distribution.
This was primarily added to support the changes made to the S-Lang
support in CIAO 3.2 - e.g. the use of require() to load modules - but
may be useful elsewhere. This does not add the functions and
variables added by slsh, e.g.: __argc, __argv, exit(),
atexit(), and stat_mode_to_string().
This support is on by default but can be turned off by adding
use Inline SLang => CONFIG => 'none';
to your script.
General documentation clean up (mainly minor changes). Added examples/trap_errors.pl to the distribution.
The list of changes to previous versions has been moved to Inline::SLang::Changes.
Please use the CPAN Resource Tracker at http://rt.cpan.org/NoAuth/Bugs.html?Dist=Inline-SLang to check for bugs, report new ones, and request new features.
Inline::SLang::Config, Inline::SLang::Changes, Inline::SLang::Types, Inline::SLang::Array, Inline::SLang::Assoc, Inline::SLang::Struct, Inline::SLang::Details, Term::Slang
For information about using Inline, see Inline.
For information about other Inline languages, see Inline-Support.
For information about S-Lang see http://www.s-lang.org/.
John Davis (for S-Lang), Brian Ingerson (for the Inline framework), and Neil Watkiss since I based much of this module on his Inline::Python and Inline::Ruby modules.
However, please do not assume that any errors in this module are in any way related to the above people.
Doug Burke <djburke@cpan.org>
This software is Copyright (C) 2003, 2004, 2005 Smithsonian Astrophysical Observatory. All rights are reserved.
It is released under the GNU General Public License. You may find a copy of this licence in the file LICENSE within the source distribution or at http://www.fsf.org/copyleft/gpl.html
Prior to version 0.04 the module was distributed under the same terms as Perl.
There is no warranty. Please see the GNU General Public License for more details.
| Inline-SLang documentation | view source | Contained in the Inline-SLang distribution. |