Array examples from Inline::SLang
The following code and examples can be found in the Inline::SLang distribution available from CPAN. The output was created using version 1.00 of the module, using the PDL support, together with version 1.4.9 of the S-Lang library.
Since the support for arrays in S-Lang and Perl do not match, the conversion of array values between the two languages is not entirely seemless, as shown in the examples below. The datatypes example page may also be useful. The support for arrays is described in the Inline::SLang::Array documentation that comes with the module.
Array references can be - and indeed are - used, but there is a potential loss of information (about the data type and size of the array, not with the array contents) in the conversion and the conversion is not very efficient. Piddles - the fundamental data object of the Perl Data Language - are a much better choice, since the conversion is much quicker and you do not lose information about data type and array size; however, this is only good for numeric types and if you have PDL installed. The third option is to use a Perl Array_Type object to store the data; the Array_Type class is part of Inline::SLang and is as inefficient as using an array reference but does retain knowledge about the array size and type.
The short version of the previous paragraph is that you should use piddles for numeric arrays and array references for the rest. The Array_Type object is probably going to be rarely used.
A simple example
use Inline 'SLang'; # you can send arrays to S-Lang print_in_slang( [ 1, 2, 4 ] ); # and get them back from S-Lang $aref = get_from_slang(); print "The array contains: " . join(',', @$aref) . "\n"; __END__ __SLang__ define print_in_slang (arr) { variable adims, ndim, atype; ( adims, ndim, atype ) = array_info(arr); vmessage( "Array has type=%S with %d dims", atype, ndim ); foreach ( arr ) { variable val = (); vmessage( " Value = %s", string(val) ); } } define get_from_slang() { return ["a string","another one","3"]; }
which, when run, produces
Array has type=Integer_Type with 1 dims Value = 1 Value = 2 Value = 4 The array contains: a string,another one,3
Using sl_array
use Inline 'SLang' => Config => EXPORT => [ 'sl_array', 'Integer_Type' ]; use Inline 'SLang'; my $aref = [ 1, 3, 2 ]; foo( $aref ); foo( sl_array( $aref, "Int_Type" ) ); foo( sl_array( $aref, [3] ) ); foo( sl_array( $aref, [3], Integer_Type() ) ); __END__ __SLang__ define foo(x) { vmessage("Array has type: %S", _typeof(x) ); }
which, when run, produces
Array has type: Integer_Type Array has type: Integer_Type Array has type: Integer_Type Array has type: Integer_Type
Array information
In this example we use a variety of methods to find out information about the array, such as its type and dimensionality.
use strict; use Inline 'SLang' => Config => EXPORT => [ 'sl_array2perl' ]; use Inline 'SLang'; # use array references for all S-Lang arrays sl_array2perl(0); my $a0 = get_array(); print "Array returned as an " . ref($a0) . "\n"; print " dim size = " . (1+$#$a0) . "\n"; # use Array_Type for all S-Lang arrays sl_array2perl(1); my $a1 = get_array(); print "Array returned as an " . ref($a1) . "\n"; my ( $dims, $ndim, $atype ) = $a1->array_info(); print " dim size = $$dims[0]\n"; print " type = $atype\n"; # use a piddle (assumes Inline::SLang::sl_have_pdl() == 1) sl_array2perl(2); my $a2 = get_array(); print "Array returned as an " . ref($a2) . "\n"; print " dim size = " . $a2->getdim(0) . "\n"; print " type = " . $a2->type . "\n"; __END__ __SLang__ define get_array() { return [ 14.0, 3 ]; }
which, when run, produces
Array returned as an ARRAY dim size = 2 Array returned as an Array_Type dim size = 2 type = Double_Type Array returned as an PDL dim size = 2 type = double
Using array references to represent arrays in Perl
In most cases the conversion between S-Lang and Perl arrays should be obvious, as this example hopes to demonstrate. The next example uses piddles rather than array references.
use strict; use Inline 'SLang'; use Data::Dumper; # ensure that we convert S-Lang arrays to array references Inline::SLang::sl_array2perl(0); my $a1 = send_and_get( [ "hi", "there", "", "a string" ] ); print "\nPerl sent:\n", Dumper($a1), "\n"; __END__ __SLang__ define send_and_get (in) { if ( typeof(in) != Array_Type ) error( "Error!" ); variable adims, ndims, atype; ( adims, ndims, atype ) = array_info(in); vmessage( "S-Lang sent a %d dim array of %S variables", ndims, atype ); variable elem; foreach ( in ) { elem = (); vmessage( " element = '%S'", elem ); } % create the output array variable out = [2:7]; reshape( out, [2,3] ); return out; }
The output of this code is:
S-Lang sent a 1 dim array of String_Type variables element = 'hi' element = 'there' element = '' element = 'a string' Perl sent: $VAR1 = [ [ 2, 3, 4 ], [ 5, 6, 7 ] ];
Using piddles to represent numeric arrays in Perl
In the previous example we made sure that S-Lang arrays were converted to array references; here we use piddles (for numeric arrays).
use strict; use Inline 'SLang'; use PDL; # ensure that we convert numeric S-Lang arrays to piddles Inline::SLang::sl_array2perl(2); # NOTE: # in S-Lang we have a [2,3] array but # in PDL this is a [3,2] array! # my $a1 = send_and_get( sequence(5)/2.0 ); print "\nPerl sent:\n", $a1->info, "\n"; print $a1, "\n"; __END__ __SLang__ define send_and_get (in) { if ( typeof(in) != Array_Type ) error( "Error!" ); variable adims, ndims, atype; ( adims, ndims, atype ) = array_info(in); vmessage( "S-Lang sent a %d dim array of %S variables", ndims, atype ); variable elem; foreach ( in ) { elem = (); vmessage( " element = '%S'", elem ); } % create the output array variable out = [2:7]; reshape( out, [2,3] ); return out; }
The output of this code is:
S-Lang sent a 1 dim array of Double_Type variables element = '0' element = '0.5' element = '1' element = '1.5' element = '2' Perl sent: PDL: Long D [3,2] [ [2 3 4] [5 6 7] ]
Note: as indicated in the example code, the array dimensions are reversed when converting between S-Lang arrays and piddles (it is only relevant for arrays with more than one dimension). This is because S-Lang uses the C-style of indexing arrays - the last index loops fastest - whilst PDL uses the FORTRAN-style of indexing, where the first index loops fastest.