man CORBA::ORBit::mapping () - CORBA mapping for Perl

NAME

Mapping - CORBA mapping for Perl

[ 29 May 2002 ]

DESCRIPTION

This document describes a mapping of the CORBA system into Perl. It sticks most closely to the mapping in the CORBA::MICO and CORBA::ORBit module, however some reference is also made to the mappings implemented in COPE and ILU/Perl.

These systems exhibit a wide diversity in the details of their object adaptors. CORBA::MICO implements most of the POA specification fashion, including all activation modes, CORBA::ORBit implements a smaller subset of the POA, COPE implements a version of the BOA, and ILU has its own object native adaptor different from the BOA, though it implements some of the BOA specification through compatibility classes.

For this reason, the description of object adaptor details, in this document is not canonical, though it is expected that implementations that implement the POA should stick closely to what is described here.

Details about the manner in which the ORB is initialized and interface definitions are loaded are not specified here. Conformant implementations may either use conventional stubs or access interface definitions in a dynamic manner. (By loading them from an Interface Repository, or by parsing .idl files at runtime).

The design goal for this mapping was to allow the complete CORBA specification to be accessed from Perl in a convenient and concise manner, even when this requires sacrificing some amount of speed or convenience for the ORB implementor.

Scoped Names

Names in Perl are identical to those in CORBA IDL. For instance, an interface CWFoo defined in module CWM, is mapped into the Perl package CWM::Foo.

It should be noted however that Perl package names do not constitute nested scopes. That is, within the package CWM::Foo, the package CWM:Foo::Bar cannot be referred to as CWBar, but must be specified by the fully qualified name CWM::Foo::Bar.

Also, there is no inheritance of scope. If a constant CWM::Foo::const1 is defined in CWM::Foo and CWM::Bar inherits from CWM::Foo, this constant cannot be referred to as CWM::Bar::const1.

Mapping for Basic Types

Unsigned CWshort, CWlong, CWfloat, CWdouble, and CWoctet all map to Perl scalar variables. CWchar maps to a string of length 1. CWboolean maps as expected for Perl. That is, a CORBA CWboolean maps to "" if false and to 1 if true. A Perl scalar maps to CORBA::TRUE if it is true, and CORBA::FALSE otherwise.

The remaining numeric types mapped to blessed objects. CWlong long maps to objects in the package CWCORBA::LongLong, CWunsigned long long maps to objects in the package CWCORBA::ULongLong, CWlong double maps to objects in the package CWCORBA::LongDouble. CWfixed maps to objects in the package CWCORBA::Fixed.

All of these packages provide overloading for the basic numeric operations. For the CWCORBA::LongLong, CWCORBA::ULongLong, and CWCORBA::LongDouble, the mapping is one-to-one.

For CWCORBA::Fixed, each object has a scale which is propagated in arithmetic operations, but no fixed number of digits. Arithmetic operations other than division are done at infinite precision; the result of division is truncated at 31 digits. When the CORBA::Fixed object is provided as an argument to a CORBA call with the argument type specified CWfixed<d,s>, the CWCORBA::Fixed object will be rounded to scale CWs and padded or truncated on the left to CWd digits.

Providing an value not in one of the above classes to a numeric operation expecting the corresponding type will give the same result as converting the value to a string by Perl's normal rules, then creating a value in the corresponding class from that string.

Mapping for constructed types

Structures
A structure maps to a hash reference with keys which are the names of the members. That is:
  struct S {
     short a;
     string b;
  };
maps to the hash reference:
  {
     a => 42,
     b => "some string"
  }
Enumerations
Enumerations map to strings corresponding to the (unscoped) names of the members.
Sequences
Sequences of CWoctet and CWchar map to Perl strings. Other sequences map to array references.
Arrays
Arrays map to Perl array references. Multiple dimensional arrays map to nested Perl array references.
TypeCodes
A typecode maps to a Perl object of type CORBA::TypeCode. The constructor takes one argument, the type of the typecode as a CORBA interface repository id.
  e.g. A type code representing a struct "Bar" by someone working for
       foo.com
  my $tc = CORBA::TypeCode->new("IDL:foo.com/Bar:1.0");
You may also access the id and name members:
  my $id = $tc->id();
  my $name = $tc->name();
Anys
An any maps to a Perl object of type CORBA::Any. The constructor takes two arguments, the type (of type CORBA::TypeCode) and the value. The type and value are accessed via the type() and value() member functions.
  e.g. To create an any containing a "Bar" structure.
  my $bar = { "data1" => 1 };   
  my $a  = CORBA::Any->new($tc, $bar);
  Note that $tc is constructed above in the TypeCode example. 
  $bar is the perl representation of a CORBA structure with one
  integer member called "data1".
Unions
A union maps into a two element array reference. The first element is the discriminator, the second, value of the arm selected by that discriminator. If the discriminator does not match one of the arms of the union, and their is no default arm, the second element will be an undefined value.

Constants

Constants defined in IDL map to a Perl subroutine which returns the value of the constant.

Objects

CORBA object references are opaque perl objects.

Attributes

Attributes are mapped to a pair of methods with names which are the attribute name prepended with CW_set_ and CW_get_. The CW_set_ method (not present for CWreadonly attributes) takes a single parameter of the type of the attribute. The CW_get_ method returns a value of the type of the attribute.

Operations

Operations are mapped to method calls. CWin parameters are mapped to parameters normally, CWinout parameters get an extra reference, and CWout parameters are returned as part of a list.

For instance, the operation:

   char foo(in long l, inout string b, out float f);

would be called as:

   ($c,$f) = $obj->foo($l, \$s);

Exceptions

Exceptions are implemented using the Error module by Graham Barr. To throw an exception, use the CWthrow method in the Exception package:

  throw MyInterface::MyException field1 => 'red', field2 => 32;

To catch an exception, use a CWtry...catch statement.

  try {
     $foo->runit();
  } catch MyInterface::MyException with {
     $e = shift;
     print "Caught a $e->{field1} exception";
  }

Object Implementations

The POA supports modes of operation where a single servant may incarnate multiple object references. For this reason, it is not, in general, permissible to supply a servant where an object reference is required. However, in situations where it is valid to call the _this() method of the servant, an ORB may transparently do this when a servant is used in place of an object reference.

Implementing interfaces

The implementation of an interfaces is defined by deriving from the package corresponding to the interface prepended with POA_.

  package MyAccount;
  @MyAccount::ISA = qw(POA_Bank::Account);
  sub new {
    my $self = bless {
                      current_balance => 0
                     };
  }
If the implementation of a interface inherits in addition from the implementation of a base interface, then the module for the interface being implemented directly must appear in the CW@ISA array before the base interface implementation. For instance, when implementing the following IDL:
  module Foo {
     interface A { long method1(); };
     interface B : A { long method2(); }
  }
with the following Perl code;
  package MyA;
  @MyA::ISA = qw(POA_Foo::A);
  sub method1 {
      return 1;
  }
  package MyB;
  @MyA::ISA = qw(POA_Foo::B MyA);
  sub method2 {
     return 2;
  }
  sub new {
     my $self = bless {};
  }
CWPOA_Foo:B must come first in CWMyB's CW@ISA. (The rational for this is that the ORB will use a hidden method in order to identifiy the class that a servant implements.) A servant is simply an Perl object blessed in a package implemented as above.

Implementing operations and attributes

Operations and attributes are implemented exactly as expected from the client-side mapping. That is, the operation is called with the same parameters as a client would use to invoke the operation.

PortableServer routines

In general, the POA routines map from their description in the .idl file as specified above. One major exception to this rule is the policy objects and the create_POA routine. There are no policy objects, instead, the create_POA routine is variadic, with the additional arguments being key-value pairs specifying Policy values. For example:

  $root_poa->create_POA ("MyPOA", undef,
                         id_assignment => 'MULTIPLE_ID',
                         lifetime => 'PERSISTENT');

Mapping for ServantManager

The opaque Cookie type maps to an arbitary Perl value.

AUTHOR

Owen Taylor <otaylor@redhat.com>