Douglas Burke > Inline-SLang > Inline::SLang::Types

Download:
Inline-SLang-1.00.tar.gz

Annotate this POD

CPAN RT

Open  0
View/Report Bugs
Source  

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.

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.

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.

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:

Array_Type Objects

See Inline::SLang::Array.

Assoc_Type Objects

See Inline::SLang::Assoc.

Struct_Type Objects

See Inline::SLang::Struct.

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 is undef.

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

syntax highlighting: