=head1 NAME Inline::SLang::Types - Support for S-Lang types in Perl =head1 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 F - 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 =head1 DESCRIPTION The aim of the type-handling in C 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 I 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 C and in Perl we choose to use a C 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 C variable in S-Lang (well, not without telling the computer this is what we wanted). Version 0.20 introduces support for the L; unfortunately the code needs some issues thrashed about a bit - namely handling of > 1D piddles/arrays. It has been released to garner user comments. =head2 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 I include all synonyms for a type, although they are recognised; for instance the C is accepted but converted to C. See L for further details. =over 4 =item * NULL Converted to a Perl undef. =item * [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. =item * [Float|Double]_Type Converted to a Perl floating-point number. =item * Complex_Type Converted to a Perl C object. =item * String_Type Converted to a perl string. =item * Array_Type Converted to one of: a Perl array reference, a Perl C object, or a I. =item * Assoc_Type Converted to a Perl C object. =item * Struct_Type and "named" structures Struct_Type variables are converted to a Perl C object, whilst "named" structures are converted to objects with the same name as the S-Lang struct name. =item * DataType_Type Converted to a Perl C object. =item * 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 I 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. =back =head2 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 C; we could create an I 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 L for further details. =over 4 =item * undef Converted to C (i.e. S-Lang's C datatype). =item * Integer Converted to S-Lang's C. =item * Floating Point Converted to S-Lang's C. =item * C Converted to S-Lang's C. =item * String Converted to S-Lang's C. =item * Array reference Converted to a S-Lang array with (hopefully) the correct datatype and dimensionality. =item * Perl C object Converted to a S-Lang array with datatype and dimensionality matching that of the Perl object. =item * Piddles Will be be converted to a S-Lang array with datatype and dimensionality matching that of the Perl object. =item * Hash reference Converted to S-Lang's C. =item * Perl C object. Converted to S-Lang's C with the datatype of the array being determined by the contents of the object. =item * Perl C and derived objects. Converted to the matching S-Lang type (C or the "named" struct). =item * Perl C object. Converted to S-Lang's C. =item * "Opaque" objects S-Lang data types that are handled as so-called "opaque" variables are converted back into the correct S-Lang variable type. =back =head1 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 L module which is distributed with Perl; arrays can be handled in a variety of ways - as a perl array reference, an C object, or a piddle (see the documentation for the L); and for other types we use a class specific to C. =over 2 =item * Complex numbers Complex numbers are represented as C in S-Lang and as a L object in Perl. See the L documentation for information on how to use this class. =item * Struct_Type and "named" structs S-Lang structures - variables with a type of C - are represented using C objects in Perl. Named structs - ie those created via a C call - are represented using C objects in Perl; these objects are sub-classes of the C 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 L for more information. =item * Associative arrays S-Lang associative arrays (C) are represented in Perl as C objects. These objects behave just as hash references do but have additional methods to match the S-Lang language. See L for more information. =item * Arrays Support for S-Lang arrays (C) comes in three "flavours": =over 2 =item 1 As a Perl array reference. =item 2 As a piddle (if you are using the L). As of version B<0.20> this support is definitely experimental; see L for more details. =item 3 As a Perl C object. It is expected that this object will I be used, at least directly. =back See L for more information. =item * S-Lang data type. S-Lang C values are represented using Perl C objects, which are described below. =item * 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 C<< >>, where C<< >> is the name of the S-lang datatype (i.e. the output of S-Lang's C function). Examples are the C and C 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 I the filehandle types C and C since it looks like the Perl I/O system is quite scary "under the hood" in v 5.8.0! =back =head1 PERL OBJECTS Each class provides a number of methods. These methods are not exported into the calling packages namespace, so they can I be accessed using the "object-oriented" form, i.e. $obj->foo() Note that the C method is not defined for some classes, which means you can only create them by calling a S-Lang function. =head2 Common methods All classes provide the following methods: =over 2 =item * typeof() Returns a C 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. =item * stringify() The "print" method for the objects has been over-loaded to use the C method: for most - probably all - types it will return the datatype name. =item * is_struct_type() Returns a 1 if the object represents a S-Lang structure - including "named" structures created via a C - and 0 otherwise. =back =head2 Array_Type Objects See L. =head2 Assoc_Type Objects See L. =head2 Struct_Type Objects See L. =head2 DataType_Type Objects Although you can use the C constructor described below to create a C variable, it is easier just to call the given type as a function. If you have specified C as a value in the C configuration option (see L 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 C<()> in order for Perl to recognise it as a function. The return value (C<$var> here) can be used just as the output of C<< DataType_Type->new() >> can. It is possible to use the names of type "synonyms" - such as C and C - although the value they return is of the I type and not the synonym. The class-specific methods are: =over 2 =item new() $dtype = DataType_Type->new([$type]); The C method accepts a string (C<$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 I type name. If you supply a name that does I map to a S-Lang datatype then the return value is C. In general you should probably be using the functional form described abode - i.e. use C - but this constructor can be useful when the data type is not known ahead of time. =item 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'. =back The equality and inequality operators - namely C<==>, C, C, and C - have been over-ridden to work for variables containing C 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 C option provided by L, as described in the L<"What functions and namespaces have been bound to Perl?"|Inline::SLang::Config/"What functions and namespaces have been bound to Perl?"> section of Inline::SLang::Config. =head2 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 C and C S-Lang variable types. The Perl objects can I be created from S-Lang (i.e. there are no C 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 I 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 F 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 C variables (this is also available as F): 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 C value (in S-Lang) has been converted into a Perl C value. =head1 SEE ALSO L, L, L, L, L, L, L