The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Inline::SLang - Write Perl subroutines in S-Lang.

SYNOPSIS

  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 "Just Another " + string(type) + " Hacker!";
  }

DESCRIPTION

The Inline::SLang module allows you to put S-Lang source code directly "inline" in a Perl script or module. It 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. 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.

What is S-Lang?

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 the Inline::SLang Module

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.

S-Lang Functions

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()!

But all I want to do is use this S-Lang module?

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 needs to be loaded via evalfile.

S-Lang Variables

We currently 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 foo() and bar() routines below:

  variable foobar = "a string";
  define foo()  { return foobar; }
  define bar(x) { foobar = x; }

It should be possible to also bind variables, but this is not a high priority (and may never be).

Supported Data Types

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 assumes that yor S-Lang library has been compiled with support for both floating-point and complex numbers.

Perl routines

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_array2perl

Usage:

  $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.

With no PDL support

If PDL support was not compiled in to the module then the flag can either be 0 or 1, where

0

All arrays are converted to a Perl array reference.

1

All arrays are converted to a Perl Array_Type object

With PDL support

If PDL support is available - version 0.11 does not include such support - then there are four options:

0

All arrays are converted to a Perl array reference.

1

All arrays are converted to a Perl Array_Type object

2

Numeric arrays are converted to piddles and non-numeric arrays are converted to a Perl array reference.

3

Numeric arrays are converted to piddles and non-numeric arrays are converted to a Perl Array_Type object.

Inline::SLang::sl_array

Usage:

  $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).

Example:

  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 (i.e. the Perl Data Language support that is not yet available). This routine is more useful for arrays of non-numeric data types.

Inline::SLang::sl_eval

Usage

  [ 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).

Example:

  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 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 );
  }

Inline::SLang::sl_have_pdl

Usage:

  $flag = Inline::SLang::sl_have_pdl();

Returns 1 if the module was compiled with support for PDL, and 0 otherwise.

Inline::SLang::sl_typeof

Usage:

  $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 for more information on how S-Lang variables are represented in Perl.

Example:

  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.

Inline::SLang::sl_version

Usage:

  $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.

CHANGES

v0.11 Wed May 7 00:39:17 EDT 2003

This release makes a couple of improvements to version 0.10 and includes infrastructure changes to support PDL (although piddles are still not supported). The major changes are:

  • S-Lang arrays can now be converted to the Perl Array_Type object as well as array references. The behaviour is controlled by the Inline::SLang::sl_array2perl() function, described in Inline::SLang.

  • It is now easier to create Perl scalars that contain a DataType_Type object: use the functions Inline::SLang::<datatype name>() instead of DataType_Type->new( "<datatype name>" );. Use '!types' in the EXPORT configuration option to import all these functions.

  • DataType_Type objects can now be compared for equality (==, eq) and inequality (!=, ne).

v0.10 Sat May 3 19:39:00 EDT 2003

There have been a number of significant enhancements and changes in this release, which is why the release number has been bumped-up to the lofty heights of 0.10.

The really-short summary is that all variables should now be supported and the support for S-Lang's associative arrays, normal arrays, and structures has been made much -more Perl like.

  • Support for S-Lang libraries earlier than 1.4.7 has been discontinued.

  • Perl class names have been changed from Inline::SLang::XXX to XXX.

  • S-Lang structs (both Struct_Type and named structs) are stored using a Perl object (also called Struct_Type) which can be treated as a hash reference. As an example, if the S-Lang structure has a field x and it is stored in the Perl variable $foo then you can access the field as $$foo{x}.

  • S-Lang Assoc_Type arrays are now converted to the Perl Assoc_Type class (and vice-versa). This object can be treated as a hash reference. When calling S-Lang functions, hash references are converted to S-Lang as an Assoc_Type [Any_Type] array.

  • Arrays can now be converted between Perl (array references or Perl Array_Type objects) and S-Lang (Array_Type variables) for any S-Lang data type. Any dimension of array supported by S-Lang is now available (in previous only one and two dimensional arrays could be used).

    Support for piddles is not yet available (planned soon).

  • Several Inline::SLang::XXX routines can now be exported to Perl's main package by use of the EXPORT configuration option (rather than the standard Perl way of using 'use foo qw( ... );'. This can be looked at as something of a hack.

  • Handling of S-Lang errors has been improved: they are now caught and then converted into Perl errors (i.e. calls to croak). This means that calling DataType_Type->new() with an unknown type name no longer results in S-Lang error messages printed to STDERR (which it did in 0.06).

  • fixed mem leak when converting structs from Perl to S-Lang. Note that the code used *may* trigger a mem leak in the S-Lang library if you are using a version < 1.4.9.

v0.06 Thu Apr 3 22:36:54 EST 2003

Notable changes are:

  • Essentially all S-Lang scalars can now be converted to Perl. Those without a direct translation to a native Perl type are converted to "opaque" Perl objects, with classes called Inline::SLang::XXX where XXX equals the name of their S-Lang data type. Essentially all you can do with these objects is pass them back to S-Lang routines. However, it does mean you can now call routines that return module-defined types.

    Currently the S-Lang file types (so File_Type and FD_Type) are converted using this scheme, which means you can not use them with Perl I/O commands. I need to read up a lot more on Perl's I/O mechanism before I can change this (if it's possible).

  • "Named" structures - e.g. Foo_Type created by typedef struct {...} Foo_Type; - are now handled as Inline::SLang::XXX objects, where XXX matches the structure type (so Foo_Type in this example). These classes are sub-classes of Inline::SLang::Struct_Type.

  • Fixed handling of BIND_NS => "All".

  • Added an examples/ directory to the distribution, which contains simple examples (mainly from Inline::SLang::Types). Note that these files are not installed into the Perl tree by 'make install'.

v0.05 Fri Mar 14 11:57:31 EST 2003

Notable changes are:

  • Handling of 'foreign' S-Lang types - those for which we have introduced special classes such as DataType_Type variables - has been changed to use a scheme in which the Perl class name is formed from the concatanation of Inline::SLang:: and the S-Lang type (so Inline::SLang::struct has been renamed to Inline::SLang::Struct_Type).

    The classes are also more uniform in that they have a number of common functions and, where possible, the method names are similar to S-Lang functions with the same functionality.

  • Ref_Type variables are now supported (scalars only) via the Inline::SLang::Ref_Type class. Unfortunately this requires use of function/types that are not part of the public interface of the S-Lang library.

  • The BIND_NS option only works for v1.4.3 and higher of S-Lang. The option has been enhanced to allow namespace "renaming" and the use of "All" to specify all known namespaces (this only works for v1.4.7 and higher of S-Lang). The only valid string options are now "Global(=...)" and "All".

  • The BIND_SLFUNCS option has been added to allow you to use slected S-Lang intrinsic functions directly from Perl (i.e. without having to write a S-Lang wrapper function around it). To help avoid nameclashes you can chose your own name for the function in Perl.

  • Documentation on S-Lang specific configuration options has been moved to Inline::SLang::Config.

v0.04 Fri Mar 7 00:14:47 EST 2003

Notable changes are:

  • License changed to GNU GPL and copyright holder to SAO.

  • Now binds all functions (other than S-Lang intrinsic functions) in the Global namespace. Added the BIND_NS configuration option to allow functions in other namespaces to be bound as well. Use the Inline '-MInline=INFO' option to find out what functions have been bound.

  • S-Lang Struct_Type variables are converted to Inline::SLang::struct objects. There are memory leaks!

  • Fixed memory leaks when converting Assoc_Type arrays to Perl.

  • S-Lang Struct_Type variables are converted to Inline::SLang::struct objects.

v0.03 Tue Jan 28 12:01:49 EST 2003

Initial public release

SUPPORTED PLATFORMS

I do not have the time to support anything but a recent version of S-Lang - defined as 1.4.7 or higher - on Solaris and Linux machines. This will hopefully extend to Mac OS X and Alpha machines in the near future.

The code is NOT guaranteed to work with an earlier version; in fact Makefile.PL should have screamed at you and gone off in a sulk if you tried to build againt an earlier version.

It is intended to support Perl versions >= 5.6.0 only (at least the release versions rather than the development releases). However note that the development is made using version 5.8.0, and so there may be subtle/hidden issues with the 5.6.x series of Perl. It is not clear yet whether we really need any >= 5.6.0 functionality, but this restriction does make testing/developing a lot easier for me.

BUGS AND DEFICIENCIES

This is alpha release code. So, by design, there will be lots of bugs and deficiencies.

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.

SEE ALSO

Inline::SLang::Config, Inline::SLang::Types, 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/.

ACKNOWLEDGEMENTS

John Davis (for S-Lang), Brian Ingerson (for the Inline framework), and Neil Watkiss since I stole virtually everything from 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.

AUTHOR

Doug Burke <djburke@cpan.org>

COPYRIGHT

This software is Copyright (C) 2003 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.

WARRANTY

There is no warranty. Please see the GNU General Public License for more details.

4 POD Errors

The following errors were encountered while parsing the POD:

Around line 175:

Expected text after =item, not a number

Around line 193:

Expected text after =item, not a number

Around line 197:

Expected text after =item, not a number

Around line 202:

Expected text after =item, not a number