Datatype 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.
It is no use being able to call S-Lang functions if you can not deal with the values it returns. Simple types such as scalars (integers, reals, and strings) are handled using native types wherever possible. So-called "opaque" types - in general those defined by a module but it does include several of the standard types defined by the S-Lang interpreter - are converted to Perl objects and should be left alone.
In the examples below we show a number of ways that data can be moved back and forth between S-Lang and Perl. For information on specific types of conversion please see the following examples pages: arrays; associative arrays; and structures. The type support is described in the Inline::SLang::Types documentation that comes with the module.
Basic datatypes
# # Examples taken from the introduction to the # Inline::SLang::Types documentation # use Inline SLang => Config => BIND_SLFUNCS => [ "vmessage" ]; use Inline SLang; use Math::Complex; # the S-Lang Complex_Type variable is automatically converted # to a Math::Complex object in Perl. # my $val = makecplx(); print "Perl has been sent $val\n"; # the multiplication is done using Math::Complex objects and # the result then converted to a S-Lang Complex_Type variable, # since vmessage is a S-Lang function [the %S means convert # the variable to its string representation] # vmessage( "S-Lang has been sent %S", $val * cplx(0,1) ); my $type = typecplx($val); print "And the S-Lang datatype is $type\n"; print " Perl object " . $type->typeof . "\n"; __END__ __SLang__ define makecplx() { return 3 + 4i; } define typecplx(cval) { return typeof(cval); }
which, when run, produces
Perl has been sent 3+4i S-Lang has been sent (-4 + 3i) And the S-Lang datatype is Complex_Type Perl object DataType_Type
The typeof function
# want to bind the typeof function # use Inline SLang; my $a0 = getfoo(0); my $a1 = getfoo(1); my $a2 = getfoo(2); print "\nIn Perl:\n"; printf "typeof(foo[0]) = %s\n", $a0->typeof; printf "typeof(foo[1]) = %s\n", $a1->typeof; printf "typeof(foo[2]) = %s\n", defined($a2) ? $a2->typeof : "undef"; __END__ __SLang__ variable foo = Any_Type [3]; foo[0] = "a string"; foo[1] = 23; define getfoo(x) { return foo[x]; } message( "In S-Lang:" ); vmessage( "typeof(foo[0]) = %s", string(typeof(foo[0])) ); vmessage( "typeof(foo[1]) = %s", string(typeof(foo[1])) ); vmessage( "typeof(foo[2]) = %s", string(typeof(foo[2])) );
which, when run, produces
In S-Lang: typeof(foo[0]) = Any_Type typeof(foo[1]) = Any_Type typeof(foo[2]) = Null_Type In Perl: typeof(foo[0]) = Any_Type typeof(foo[1]) = Any_Type typeof(foo[2]) = undef
Note: the Null_Type variable in S-Lang gets converted to a Perl undef.
Using references
use Inline SLang; my $ref = getfoo(); print "\$ref is a " . ref($ref) . " object\n"; print "And when printed as a string = $ref\n"; printfoo($ref); changefoo($ref,"no it isn't"); printfoo($ref); __END__ __SLang__ variable foo = "this is a string"; define getfoo() { return &foo; } define printfoo(x) { () = printf( "foo = [%s]\n", @x ); } define changefoo(x,y) { @x = y; }
which, when run, produces
$ref is a Ref_Type object And when printed as a string = Ref_Type foo = [this is a string] foo = [no it isn't]
What types are available?
The INFO option of the Inline module can be used to find out, amongst other things, what data types from S-Lang are recognised by the module. The following example:
# # Use this via 'perl -Mblib -MInline=info example/info.pl' # use Inline SLang; # let's not actually do anything __END__ __SLang__ typedef struct { foo, bar } FooBarStruct_Type; variable foobar = "a string"; define foo() { return foobar; } define bar(x) { foobar = x; }
produces the following output when the '-MInline=info' option is added to the Perl interpreter:
<-----------------------Information Section-----------------------------------> Information about the processing of your Inline SLang code: Your source code needs to be compiled. I'll use this build directory: /data/dburke2/www/perl-slang/examples/_Inline/build/info_pl_9cef and I'll install the executable as: /data/dburke2/www/perl-slang/examples/_Inline/lib/auto/info_pl_9cef/info_pl_9cef.sldat Configuration details --------------------- Version of S-Lang: 1.4.9 Perl module version is 1.00 and supports PDL The following S-Lang types are recognised: Int32_Type UInteger_Type _IntegerP_Type FooBarStruct_Type[Struct_Type] Int_Type Struct_Type ULong_Type FD_Type Long_Type Float_Type Array_Type UInt32_Type File_Type UInt_Type UChar_Type UShort_Type Double_Type Float64_Type Int16_Type Float32_Type Null_Type Integer_Type BString_Type Char_Type Undefined_Type Short_Type Any_Type Assoc_Type Ref_Type Complex_Type String_Type UInt16_Type DataType_Type The following S-Lang namespaces have been bound to Perl: 2 functions from namespace Global are bound to package main bar() foo() <-----------------------End of Information Section---------------------------->
Further messing around with types
In this somewhat convoluted example, the S-Lang routine bar() returns a number of variables which we then inspect with the printval() routine (written in Perl). It is just intended to show that you can convert arbitrarily complex data structures between Perl and S-Lang - assuming that the individual components can be converted that is!
use strict; use Inline 'SLang'; use Data::Dumper; # this is not meant to be a robust, general purpose, printing routine! sub printval ($;$); sub printval ($;$) { my $x = shift; my $depth = shift || 0; my $ref = ref($x); my $spacer = ' ' x $depth; unless ( $ref ) { print "${spacer}Scalar: $x\n"; return; } if ( $ref eq "ARRAY" ) { print "${spacer}Array:\n"; print "${spacer} " . Dumper($x) . "\n"; return; } if ( $ref eq "Struct_Type" ) { print "${spacer}Struct_Type:\n"; while ( my ( $field, $val ) = each %{$x} ) { print "${spacer} field $field contains\n"; printval( $val, $depth+2 ); } return; } if ( $ref eq "Assoc_Type" ) { my $type = $x->_typeof; print "${spacer}Assoc_Type [$type]:\n"; while ( my ( $field, $val ) = each %{$x} ) { print "${spacer} key '$field' contains\n"; printval( $val, $depth+2 ); } return; } print "${spacer}Object: $x\n"; } # sub: printval foreach my $perlval ( bar() ) { printval($perlval); } __END__ __SLang__ define bar () { variable x = struct { foo, bar }; x.foo = 1; x.bar = Assoc_Type [String_Type]; x.bar["a a"] = "a string"; x.bar["flibble"] = "another string"; return ( 1, 2.3, ["an","array","of strings"], x, 4-3i ); }
The output of this code is:
Scalar: 1 Scalar: 2.3 Array: $VAR1 = [ 'an', 'array', 'of strings' ]; Struct_Type: field foo contains Scalar: 1 field bar contains Assoc_Type [String_Type]: key 'a a' contains Scalar: a string key 'flibble' contains Scalar: another string Object: 4-3i