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 is to allow a user to program "naturally" in Perl and S-Lang, and so native data types are used wherever possible. However, objects are used when necessary - for some ill-defined definition of necessary - to preserve type information. The type system is also changing as I use the module more and come across things that seemed fine when designing the module but are just annoying to use (hopefully there won't be too many of these changes).
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).
I promise that soon (not many more releases after v0.10) the module will support the Perl Data Language (ie PDL), since it provides variables ("piddles") which retain type information and are optimised for numeric work.
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 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
Math::Complex
object.String_Type
Converted to a perl string.
Array_Type
Converted to one of: a Perl array reference, an
Array_Type
object, or a piddle. Currently only the Perl array reference is supported.Assoc_Type
Converted to an
Assoc_Type
object.Struct_Type and "named" structures
Struct_Type variables are converted to a
Struct_Type
object, whilst "named" structures are converted to objects with the same name as the S-Lang struct name.Other S-Lang types are converted to a Perl class that matches the S-Lang type name.
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
.
See below for further details.
undef
Converted to
NULL
.Integer
Converted to S-Lang
Integer_Type
.Floating Point
Converted to S-Lang
Double_Type
.Math::Complex
Converted to S-Lang
Complex_Type
.String
Converted to S-Lang
String_Type
.Array reference
Converted to S-Lang
Array_Type
.Perl
Array_Type
objectConverted to S-Lang
Array_Type
.Piddles
Will be converted to S-Lang
Array_Type
. NOT YET AVAILABLE.Hash reference
Converted to S-Lang
Assoc_Type [Any_Type]
.Perl
Assoc_Type
object.Converted to S-Lang
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)."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; for numeric types we may use piddles (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 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 a hash reference does 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).
This is NOT YET AVAILABLE.
As a Perl
Array_Type
object.It is expected that this object will only be used rarely.
See Inline::SLang::Array for more information.
S-Lang data type.
S-Lang
Datatype_Type
values are represented using PerlDataType_Type
objects.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:
- o
-
typeof()
Returns a string containing the name of the S-Lang datatype of the object (which corresponds to the name of the Perl class).
- o
-
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 (namely the output of thetypeof()
method).The class descriptions below describe the output format if it does not match that of the
typeof()
method. - o
-
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
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' for 'Integer_Type') are accepted but automatically converted to the 'original' type name.
Note that if you supply a name that does not map to a S-Lang datatype then the return value is
undef
. - 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'.
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.
A possible future enhancement is to provide a set of functions that match the datatype name and that return a DataType_Type
object of the given class. This would then allow you to say
Integer_Type()
rather than
DataType_Type->new("Integer_Type")
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