Douglas Burke > Inline-SLang > Inline::SLang::Struct

Download:
Inline-SLang-1.00.tar.gz

Annotate this POD

CPAN RT

Open  0
View/Report Bugs
Source  

NAME ^

Inline::SLang::Struct - Support for structures

SYNOPSIS ^

  use Inline 'SLang';

  # you can send arrays to S-Lang
  # - note we use them like a hash reference
  my $s1 = Struct_Type->new( ["xx","aa","one"] );
  $$s1{xx} = 14; $$s1{aa} = "foo"; $$s1{one} = [1,2];
  print_in_slang( $s1 );

  # and get them back from S-Lang
  my $s2 = get_from_slang();
  print "The struct has a type of $s2\n";
  while ( my ( $k, $v ) = each %$s2 ) {
    print "  field $k has type ",
      (ref($v) ? ref($v) : "perl scalar"),
      " and value $v\n";
  }

  __END__
  __SLang__

  define print_in_slang (st) {
    vmessage( "S-Lang has been sent a %S structure", typeof(st) );
    foreach ( get_struct_field_names(st) ) {
      variable f = ();
      vmessage( " and field %s = %S", f, get_struct_field(st,f) );
    }
  }
  typedef struct { key1, wowza } FooStruct;
  define get_from_slang() {
    variable x = @FooStruct;
    x.key1 = "this is key 1";
    x.wowza = 4+3i;
    return x;
  }

The output of this code - which can be found in the source-code distribution as examples/structs.pl - is:

  S-Lang has been sent a Struct_Type structure
   and field xx = 14
   and field aa = foo
   and field one = Integer_Type[2]
  The struct has a type of FooStruct
    field key1 has type perl scalar and value this is key 1
    field wowza has type Math::Complex and value 4+3i

DESCRIPTION ^

S-Lang's structures can be thought of as "restricted" associative arrays, in that the keys are fixed (so no adding or deleting) and when you loop through them the order is set by the order they are given in the structure. So, we convert S-Lang structures into Perl Struct_Type objects which behave like hash references (with some additional methods).

To support "named" structures - i.e. those created using S-Lang's typedef struct { ... } SomeName; syntax, we create sub-classes of the Struct_Type class with names that match that of the structure. In this particular case that would be SomeName. Note that this only works for those typedef statements executed when the code is loaded; if you call S-Lang's eval() function with a typedef statement then that structure name will not be available as a Perl class.

Note that a bare hash reference is not converted into a S-Lang structure since this is used to represent an associative array (see Inline::SLang::Assoc).

THE STRUCT_TYPE CLASS ^

Once created, the Perl Struct_Type class behaves like a hash reference except for the following:

The Struct_Type class inherit the default methods of all the Inline::SLang classes, namely:

As with the other object classes these methods can only be called using the $object->method( args ) syntax. There are also a number of additional methods for this class:

S-Lang's stuct_set_fields() routine is currently not provided by the class but it's not hard to add (or to emulate).

Examples

Using a named structure created in S-Lang

Another simple example of using structures in Perl (this can be found in examples/types_struct.pl) is shown below:

  use Inline 'SLang' => <<'EOS';
  variable runtime = time();
  typedef struct { x, time } xTime_Struct;
  define ret1(x) {
    variable y = struct { x, time };
    y.x    = x;
    y.time = runtime;
    return y;
  }
  define ret2(x) {
    variable y = @xTime_Struct;
    y.x    = x;
    y.time = runtime;
    return y;
  }
  EOS

  # first with a normal structure
  my $s1 = ret1( "struct example" );
  print  "ret1() returned a $s1\n";
  printf "Is it a structure? [%d]\n", $s1->is_struct_type;
  printf "With keys/fields [ %s ]\n",
    join( ", ", keys(%$s1) );
  print  " s.x    = $$s1{x}\n";
  print  " s.time = $$s1{time}\n";

  # and then with a "named" structure
  my $s2 = ret2( "named struct example" );
  print  "ret2() returned a $s2\n";
  printf "Is it a structure? [%d]\n", $s2->is_struct_type;
  printf "With keys/fields [ %s ]\n",
    join( ", ", keys(%$s2) );
  print  " s.x    = $$s2{x}\n";
  print  " s.time = $$s2{time}\n";

The output of the code is going to look something like (depending on whether you keep sociable hours or not):

  ret1() returned a Struct_Type
  Is it a structure? [1]
  With keys/fields [ x, time ]
   s.x    = struct example
   s.time = Sat May  3 03:46:01 2003
  ret2() returned a xTime_Struct
  Is it a structure? [1]
  With keys/fields [ x, time ]
   s.x    = named struct example
   s.time = Sat May  3 03:46:01 2003

Using a named structure created in Perl

An example of creating a "named" structure from Perl (available as examples/named_struct.pl in the source distribution) is:

  use Inline 'SLang' => <<'EOS';
  typedef struct { x, foo } My_Struct;
  define is_okay(x) {
    if ( typeof(x) != My_Struct ) {
      vmessage("You sent me a %S", typeof(x));
      return;
    }
    vmessage( "My_Struct field x   = %S", x.x );
    vmessage( "My_Struct field foo = %S", x.foo );
  }
  EOS

  my $s = My_Struct->new();
  $$s{x}   = 1;
  $$s{foo} = "foo foo";
  is_okay( $s );

which produces:

  My_Struct field x   = 1
  My_Struct field foo = foo foo

SEE ALSO ^

Inline::SLang::Assoc, Inline::SLang

syntax highlighting: