NAME
Inline::SLang::Types - Support for S-Lang types in Perl
SYNOPSIS
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); }
The output of this code - which can be found in the source-code distribution as examples/types.pl - is:
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
DESCRIPTION
The aim of the type-handling in Inline::SLang
is to allow a user to program "naturally" in Perl and S-Lang - i.e. to take advantage of the strengths of each language - and so native data types are used wherever possible. However, Perl objects (classes defined in this module) are used when necessary - for some poorly defined definition of necessary - to preserve type information.
As an example, consider swapping a complex number between S-Lang and Perl. In S-Lang it would be represented as a Complex_Type
and in Perl we choose to use a Math::Complex
object. Something simple - such as an array reference containing two elements - could have been used, but then we would not be able to convert it back into a Complex_Type
variable in S-Lang (well, not without telling the computer this is what we wanted).
Version 0.20 of the module added support for the the Perl Data Language (ie PDL).
Supported S-Lang Data Types
The following S-Lang types may be returned from a S-Lang function to Perl. Note that the list does not include all synonyms for a type, although they are recognised; for instance the Int_Type
is accepted but converted to Integer_Type
.
See the "DATATYPE CLASSES" section below for further details.
NULL
Converted to a Perl undef.
[Char|UChar|Short|UShort|Integer|UInteger|Long|ULong]_Type
Converted to a Perl integer. The unsigned types are converted as unsigned values, whatever difference that may make.
[Float|Double]_Type
Converted to a Perl floating-point number.
Complex_Type
Converted to a Perl
Math::Complex
object.String_Type
Converted to a perl string.
Array_Type
Converted to one of: a Perl array reference, a Perl
Array_Type
object, or a piddle.Assoc_Type
Converted to a Perl
Assoc_Type
object.Struct_Type and "named" structures
Struct_Type variables are converted to a Perl
Struct_Type
object, whilst "named" structures are converted to objects with the same name as the S-Lang struct name.DataType_Type
Converted to a Perl
DataType_Type
object.Other S-Lang types are converted to a Perl class that matches the name of the S-Lang datatype. They are then treated in Perl as opaque objects, in that you can pass them back to S-Lang and let it access their contents but you can not do anything else with them in Perl.
Supported Perl Data Types
The following data types may be passed from Perl into S-Lang. Any other type results in the Perl interpreter issuing a croak
; we could create an opaque datatype to store such values - much as we do when we come across a S-Lang datatype that we don't recognise - but this would only be useful if we also allow Perl to be embedded into S-Lang.
See the "DATATYPE CLASSES" section below for further details.
undef
Converted to
NULL
(i.e. S-Lang'sNull_Type
datatype).Integer
Converted to S-Lang's
Integer_Type
.Floating Point
Converted to S-Lang's
Double_Type
.Math::Complex
Converted to S-Lang's
Complex_Type
.String
Converted to S-Lang's
String_Type
.Array reference
Converted to a S-Lang array with (hopefully) the correct datatype and dimensionality.
Perl
Array_Type
objectConverted to a S-Lang array with datatype and dimensionality matching that of the Perl object.
Piddles
Will be be converted to a S-Lang array with datatype and dimensionality matching that of the Perl object.
Hash reference
Converted to S-Lang's
Assoc_Type [Any_Type]
.Perl
Assoc_Type
object.Converted to S-Lang's
Assoc_Type
with the datatype of the array being determined by the contents of the object.Perl
Struct_Type
and derived objects.Converted to the matching S-Lang type (
Struct_Type
or the "named" struct).Perl
DataType_Type
object.Converted to S-Lang's
DataType_Type
."Opaque" objects
S-Lang data types that are handled as so-called "opaque" variables are converted back into the correct S-Lang variable type.
DATATYPE CLASSES
Objects are used to represent those S-Lang data types for which there is no corresponding Perl data type: for complex numbers we use the Math::Complex module which is distributed with Perl; arrays can be handled in a variety of ways - as a perl array reference, an Array_Type
object, or a piddle (see the documentation for the Perl Data Language); and for other types we use a class specific to Inline::SLang
.
Complex numbers
Complex numbers are represented as
Complex_Type
in S-Lang and as a Math::Complex object in Perl. See the Math::Complex documentation for information on how to use this class.Struct_Type and "named" structs
S-Lang structures - variables with a type of
Struct_Type
- are represented usingStruct_Type
objects in Perl. Named structs - ie those created via atypedef struct {} XXX
call - are represented usingXXX
objects in Perl; these objects are sub-classes of theStruct_Type
class. The objects behave similarly to a hash reference, except that you can not add or delete keys, the order of the keys is fixed to match that of the structure, and there are a number of method calls that match the S-Lang language.See Inline::SLang::Struct for more information.
Associative arrays
S-Lang associative arrays (
Assoc_Type
) are represented in Perl asAssoc_Type
objects. These objects behave just as hash references do but have additional methods to match the S-Lang language.See Inline::SLang::Assoc for more information.
Arrays
Support for S-Lang arrays (
Array_Type
) comes in three "flavours":As a Perl array reference.
As a piddle (if you are using the Perl Data Language).
As a Perl
Array_Type
object.It is expected that this object will rarely be used, at least directly.
See Inline::SLang::Array for more information.
S-Lang data type.
S-Lang
Datatype_Type
values are represented using PerlDataType_Type
objects, which are described below.Other types.
A number of S-Lang types do not map to an obvious Perl type. For these types, Inline::SLang creates an object of class
<type>
, where<type>
is the name of the S-lang datatype (i.e. the output of S-Lang'stypeof
function). Examples are theRef_Type
andAny_Type
S-Lang variable types.The objects are treated as "opaque" containers; you can store them and send them back to S-Lang but there's essentially nothing else you can do with them directly in Perl.
This currently includes the filehandle types
File_Ptr_Type
andFile_FD_Type
since it looks like the Perl I/O system is quite scary "under the hood" in v 5.8.0!
PERL OBJECTS
Each class provides a number of methods. These methods are not exported into the calling packages namespace, so they can only be accessed using the "object-oriented" form, i.e.
$obj->foo()
Note that the new()
method is not defined for some classes, which means you can only create them by calling a S-Lang function.
Common methods
All classes provide the following methods:
typeof()
Returns a
DataType_Type
object which contains the the S-Lang datatype of the object. This object will return the name of the datatype when converted to a string.stringify()
The "print" method for the objects has been over-loaded to use the
stringify()
method: for most - probably all - types it will return the datatype name.is_struct_type()
Returns a 1 if the object represents a S-Lang structure - including "named" structures created via a
typedef
- and 0 otherwise.
Array_Type Objects
See Inline::SLang::Array.
Assoc_Type Objects
See Inline::SLang::Assoc.
Struct_Type Objects
DataType_Type Objects
Although you can use the new()
constructor described below to create a DataType_Type
variable, it is easier just to call the given type as a function. If you have specified !types
as a value in the EXPORT
configuration option (see Inline::SLang::Config for more details) then you can just say:
my $var = Integer_Type();
otherwise you have to include the package name, as in the following
my $var = Inline::SLang::Integer_Type();
Note that even though the functions take no arguments you have to supply the ()
in order for Perl to recognise it as a function. The return value ($var
here) can be used just as the output of DataType_Type->new()
can.
It is possible to use the names of type "synonyms" - such as Int_Type()
and Float32_Type()
- although the value they return is of the base type and not the synonym.
The class-specific methods are:
- new()
-
$dtype = DataType_Type->new([$type]);
The
new()
method accepts a string ($type
) containing the name of the S-Lang datatype (e.g. "UChar_Type"). If no variable is supplied then "DataType_Type" is assumed. Synonyms of types (eg 'Int_Type' and 'Float32_Type') are accepted but automatically converted to the base type name. If you supply a name that does not map to a S-Lang datatype then the return value isundef
.In general you should probably be using the functional form described abode - i.e. use
Integer_Type()
- but this constructor can be useful when the data type is not known ahead of time. - stringify()
-
The name of the datatype represented by the object is returned.
For instance
$type = DataType_Type->new("Any_Type"); print("And the type is '$type'\n");
outputs
And the type is 'Any_Type'.
The equality and inequality operators - namely ==
, eq
, ne
, and !=
- have been over-ridden to work for variables containing DataType_Type
objects. So you can say:
my $val = some_function_call();
print "Got a S-Lang array\n" if
$val->typeof == Array_Type();
To see a list of all the possible datatypes recognised by a particular program use the INFO
option provided by the Inline module, as described in the "What functions and namespaces have been bound to Perl?" section of Inline::SLang::Config.
Other objects - aka "opaque" variables
These objects are used to store S-Lang data types for which there is no obvious - or perhaps easy - way to represent in Perl. Examples are the Ref_Type
and Any_Type
S-Lang variable types.
The Perl objects can only be created from S-Lang (i.e. there are no new()
methods). In fact, there is little that you can do with these objects in Perl; if you want to access/change the value referred to then you need to pass the object back to S-Lang.
There are no class-specific methods. This means that there is no way of creating one of these objects except from S-Lang (i.e. there is no object constructor in Perl).
An example using S-Lang references - available as examples/use_refs.pl in the source code - is:
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; }
The output of this script is:
$ref is a Ref_Type object
And when printed as a string = Ref_Type
foo = [this is a string]
foo = [no it isn't]
Note that to change the value pointed to by the reference we had to send the variable back to S-Lang and do the processing there.
For Any_Type
variables (this is also available as examples/use_anytype.pl):
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])) );
The output of this script is:
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 that the Null_Type
value (in S-Lang) has been converted into a Perl undef
value.
SEE ALSO
Inline::SLang::Array, Inline::SLang::Assoc, Inline::SLang::Struct, Inline::SLang, Math::Complex, PDL, PDL::Intro