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.
Inline::SLang
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.
Inline
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.
array_map()
assoc_get_keys()
main
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.
BIND_NS
BIND_SLFUNCS
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()!
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):
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.
require
evalfile
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).
require()
slsh
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:
get_foobar()
set_foobar()
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 can be used to change this.
Inline::SLang::sl_eval()
EXPORT
$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.
Array_Type
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.
$aref
$atype
"Int_Type"
DataType_Type
If you know the array dimensions then it's probably faster to supply them as the $adims argument, which should be an array reference.
$adims
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).
[3,2]
[24]
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:
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.
$str
eval()
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?):
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, and 0 otherwise.
1
0
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.
SETUP
$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.
sl_setup_slsh()
$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).
$var
typeof()
The return value is an object of the DataType_Type class; see 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.
Math::Complex
$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.
sl_eval("_slang_version_string")
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
croak
eval
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().
__argc
__argv
exit()
atexit()
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.
S-Lang library >= 1.4.7. The code has NOT been tested against version 2 of the S-Lang library and is currently unlikely to work with it.
The S-Lang library must have been compiled with support for floating-point and complex numbers. The module could be made to work without these numbers/types but I do not have the time to do this.
The only tested operating systems are Solaris, Linux, and OS-X (10.3). It should compile on UNIX-like systems (no promises though), and I will be surprised if it works without tweaking on other operating systems.
Perl >= 5.6.0 (only really tested on version 5.8).
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.
To install Inline::SLang, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Inline::SLang
CPAN shell
perl -MCPAN -e shell install Inline::SLang
For more information on module installation, please visit the detailed CPAN module installation guide.