Skip to main content
Previous sectionNext section

Using the Perl Binding

This chapter provides concrete examples of Perl code that uses the Caché Perl binding. The following subjects are discussed:

Many of the examples presented here are taken from the sample programs in <cachesys>/dev/perl/samples/ (see Default Caché Installation Directory in the Caché Installation Guide for the location of <cachesys> on your system). The argument processing and error trapping statements (try/catch) have been removed to simplify the code. See Sample Programs for details about loading and running the complete sample programs.

Perl Binding Basics

A Caché Perl binding application can be quite simple. Here is a complete sample program:

   use Intersys::PERLBIND;
   eval {
   # Connect to the Cache' database
      $url = "localhost[1972]:Samples";
      $user = "_SYSTEM";
      $password = "SYS";
      $conn = Intersys::PERLBIND::Connection->new($url,$user,$password,0);
      $database = Intersys::PERLBIND::Database->new($conn);
   
   # Create and use a Cache' object
      $person = $database->create_new("Sample.Person", undef);
      $person->set("Name","Doe, Joe A");
      print "Name: ",$person->get("Name"), "\n";
   };
Copy code to clipboard

This code imports the Intersys::PERLBIND module, and then performs the following actions:

  • Connects to the Samples namespace in the Caché database:

    • Defines the information needed to connect to the Caché database.

    • Creates a Connection object ($conn).

    • Uses the Connection object to create a Database object ($database).

  • Creates and uses a Caché object:

    • Uses the Database object to create an instance of the Caché Sample.Person class.

    • Sets the Name property of the Sample.Person object.

    • Gets and prints the Name property.

The following sections discuss these basic actions in more detail.

Connecting to the Caché Database

The basic procedure for creating a connection to a namespace in a Cache database is as follows:

  • Establish the physical connection:

      $conn = Intersys::PERLBIND::Connection->new($url,$userid,$password,$timeout);
    Copy code to clipboard

    The Connection->new() method creates a physical connection to a namespace in a Caché database. The $url parameter defines which server and namespace the Connection object will access. The Connection class also provides the new_secure() method for establishing secure connections using Kerberos. See Connections for a detailed discussion of both methods.

  • Create a logical connection:

       $database = Intersys::PERLBIND::Database->new($conn);
    Copy code to clipboard

    The Connection object is used to create a Database object, which is a logical connection that lets you use the classes in the namespace to manipulate the database.

    The following code establishes a connection to the Samples namespace:

      $address ="localhost"; # server TCP/IP address ("localhost" is 127.0.0.1)
      $port = "1972"; # server TCP/IP port number
      $namespace = "SAMPLES"; # sample namespace installed with Cache'
    
      $url = $address."[$port]:".$namespace;
      $user = "_SYSTEM";
      $password = "SYS";
    
      $conn = Intersys::PERLBIND::Connection->new($url,$user,$password,0);
      $database = Intersys::PERLBIND::Database->new($conn); 
    Copy code to clipboard

Using Caché Database Methods

The Intersys::PERLBIND::Database class allows you to run Caché class methods and connect to Caché objects on the server. Here are the basic operations that can be performed with the Database class methods:

  • Create Objects

    The create_new() method is used to create a new Caché object. The syntax is:

       $object = $database->create_new($class_name, $initial_value) 
    Copy code to clipboard

    where $class_name is the name of a Caché class in the namespace accessed by $database. For example, the following statement creates a new instance of the Sample.Person class:

       $person = $database->create_new("Sample.Person", undef);
    Copy code to clipboard

    In this example, the initial value of $person is undefined.

  • Open Objects

    The openid() method is used to open an existing Caché object. The syntax is:

       $object = $database->openid($class_name, $id, $concurrency, $timeout)
    Copy code to clipboard

    For example, the following statement opens the Sample.Person object that has an id with a value of 1:

       $person = $database->openid("Sample.Person", "1", -1, 0);
    Copy code to clipboard

    Concurrency and timeout are set to their default values.

  • Run Class Methods

    You can run class methods using the following syntax:

       $result = $database->run_class_method($classname,$methodname,LIST) 
    Copy code to clipboard

    where LIST is a list of method arguments. For example, the $database->openid() example shown previously is equivalent to the following code:

       $person = $database->run_class_method("Sample.Person","%OpenId","1");
    Copy code to clipboard

    This method is the analogous to the Caché ##class syntax. For example, the following code:

       $list = $database->run_class_method("%ListOfDataTypes","%New",undef);
       $list->Insert("blue");
    Copy code to clipboard

    is exactly equivalent to the following ObjectScript code:

       set list=##class(%ListOfDataTypes).%New()
       do list.Insert("blue") 
    Copy code to clipboard

Using Caché Object Methods

The Intersys::PERLBIND::Object class provides access to Caché objects. Here are the basic operations that can be performed with the Object class methods:

  • Get and Set Properties

    Properties are accessed through the get() and set() accessor methods. The syntax for these methods is:

       $value = $object->get($propname)
       $object->set($propname,$value)
    Copy code to clipboard

    For example:

       $person->set("Name","Adler, Mortimer");
       $name = $person->get("Name");
    Copy code to clipboard

    Private and multidimensional properties are not accessible through the Perl binding.

  • Run Object Methods

    You can run object methods by calling them directly::

       $answer = $object->MethodName(LIST);
    Copy code to clipboard

    For example:

       $answer = $person->Addition(17,20);
    Copy code to clipboard

    You can also use run_obj_method() to do the same thing:

       $answer = $object->run_obj_method($MethodName,LIST);
    Copy code to clipboard

    For example:

       $answer = $object->run_obj_method("Addition", 17, 20);
    Copy code to clipboard

    This method is useful when calling inherited methods (such as %Save or %Id) that are not directly available.

  • Save Objects

    To save an object, use run_obj_method() to call %Save:

       $object->run_obj_method("%Save")
    Copy code to clipboard

    To get the id of a saved object, use run_obj_method() to call %Id:

       $id = $object->run_obj_method("%Id") 
    Copy code to clipboard
  • Get Information about Methods and Properties

    The Object class provides several methods that return information about the methods and properties in an object. The get_methods() and get_properties() methods return either the number of available items or a list of valid item names, depending on the context:

       $methodcount = $object->get_methods(); # scalar context
       @methodlist = $object->get_methods(); # list context
    
       $propcount = $object->get_properties(); # scalar context
       @proplist = $object->get_properties(); # list context
    Copy code to clipboard

    The is_method() and is_property() methods test a string to see if it is a valid item name:

       $bool = $object->is_method($methodname);
       $bool = $object->is_property($propname); 
    Copy code to clipboard

Using Tied Variables

It is possible to tie an object returned by the Perl binding to a hash, and then access the properties of the object through the hash. For example:

   $object = $database->openid("Sample.Person", "1", -1, 0);
   $person = tie %person,"Intersys::PERLBIND::ObjectHash",( _object => $object)
   $name = $person{"Name"};
# The following line is equivalent to $person->set("Name","Tregar, Sam");
   $person{"Name"} = "Tregar, Sam"; 
Copy code to clipboard

Instead of getting the the name of person through $person->get("Name"), you can use the tie to get it through the hash, $person{"Name"}.

You can use the return value from the tie to run methods or you can use the "tied" built-in of Perl to run methods, for example:

   $ans = $person->Addition(12,17);
   print "ans=$ans\n";
   
   $ans = tied(%person)->Addition(12,17);
   print "ans=$ans\n";
Copy code to clipboard

In both cases, the value 29 is returned.

You can also use the tie to iterate through a list of properties:

   while (($property, $value ) = each(%person)) {
      print "propety=$property value=$value\n";
   }
Copy code to clipboard

Here is a complete example:

   $database = Intersys::PERLBIND::Database->new($conn);
   $personobj = $database->openid("Sample.Person", "1", -1, 0);
   
   $person = tie %person,
      "Intersys::PERLBIND::ObjectHash",( _object => $personobj);
   while (($propname, $value) = each(%person)) {
      print "property $propname = $value\n";
   }
Copy code to clipboard

This example produces the following output, displaying each property and its value:

   property Age = 61
   property DOB = 1942-01-18
   property SSN = 295-62-8728
   property Home = Intersys::PERLBIND::Object=SCALAR(0x1831ee4)
   property Name = Adler, Mortimer
   property Office = Intersys::PERLBIND::Object=SCALAR(0x183eed0)
   property Spouse = 
   property FavoriteColors = Intersys::PERLBIND::Object=SCALAR(0x1831e3c) 
Copy code to clipboard

Using Collections and Lists

Caché %Collection objects are handled like any other Perl binding object. Caché %List variables are mapped to Perl array references. The following sections demonstrate how to use both of these items.

%Collection Objects

Collections are manipulated through object methods of the Caché %Collection class. The following example shows how you might manipulate a Caché %ListOfDataTypes collection:

# Create a %ListOfDataTypes object and add a list of colors
   $newcolors = $database->run_class_method("%ListOfDataTypes","%New",undef);
   @color_list = qw(red blue green);
   for $color (@color_list) {
      $newcolors->Insert($color);
      print " added >$color<\n";
   };

# Add the list to a Sample.Person object
   $person = $database->openid("Sample.Person",$id,-1,0);
   $person->set("FavoriteColors",$newcolors);

# Get the list back from $person and print it out.
   $colors = $person->get("FavoriteColors");
   print "Number of colors: ",$colors->get("Size"), "\n";
   do {
      $color = $colors->GetNext($i);
      print " New Color #$i = $color\n" if defined($i);
   } until (!defined($i));
   
# Remove and replace the second element
   $colors->RemoveAt(2) if $colors->get("Size") > 0;
   $colors->InsertAt("purple",2);
   
# Show the changes to the collection
   print("Modified 'FavoriteColors' list:\n");
   do {
      $color = $colors->GetNext($i);
      print " Element #$i = $color\n" if defined($i);
   } until (!defined($i));
Copy code to clipboard

%List Variables

The Perl binding maps Caché %List variables to Perl array references.

Caution:

While a Perl array has no size limit, Caché %List variables are limited to approximately 32KB. The actual limit depends on the data type and the exact amount of header data required for each element. Be sure to use appropriate error checking (as demonstrated in the following examples) if your %List data is likely to approach this limit.

The examples in this section assume the following Caché class:

   Class Sample.List Extends %Persistent
   {
   Property CurrentList As %List;
   
   Method InitList() As %List { 
      q $LB(1,"hello",3.14) }
   
   Method TestList(NewList As %List) As %Integer {
      set $ZTRAP="ErrTestList"
      set ItemCount = $LISTLENGTH(NewList)
      if (ItemCount = 0) {set ItemCount = -1}
      q ItemCount
   ErrTestList
      set $ZERROR = ""
      set $ZTRAP = ""
      q 0 }
   }
Copy code to clipboard

The TestList() method is used to test if a Perl array is a valid Caché list. If the list is too large,the method traps an error and returns 0 (Perl false). If the list is valid, it returns the number of elements. If a valid list has 0 elements, it returns -1.

Example 1: Caché to Perl

The following code creates a Sample.List object, gets a predefined Caché list from the InitList() method, transforms it into a Perl array, and displays information about the array:

   $listobj = $database->create_new("Sample.List",undef);
   $arrayref = $listobj->InitList();
   @array = @$arrayref;
   
   print "Initial List from Cache:\n";
   print "array address = $arrayref\n";
   print "array contents = @array\n";
   print "There are ",scalar(@array)," elements in the list:\n";
   for ($i=0;$i<scalar(@array);$i++) {
      print " element ",$i+1," = [$array[$i]]\n";
   }
Copy code to clipboard

This code produces the following output:

   Initial List from Cache:
   array address = ARRAY(0x18d3d04)
   array contents = Cache to Perl: hello! 1 3.14
   There are 4 elements in the list:
      element 1 = [Cache to Perl: hello!]
      element 2 = [1]
      element 3 = []
      element 4 = [3.14]
Copy code to clipboard

In element 3, the null list element in Caché corresponds to value of undef in the Perl array.

Example 2: Perl to Caché and Back Again

The following code passes a list in both directions. It creates a small Perl array, stores it in the Caché object's CurrentList property, then gets it back from the property and converts it back to a Perl array.

   @oldarray = (1, undef, 2.78,"Just a small list.");
   $listobj->set("CurrentList",\@oldarray);
   $arrayref = $listobj->get("CurrentList");
   @newarray = @$arrayref;

   print "\n\nThis list is from property CurrentList:\n";
   print "There are ",scalar(@newarray)," elements in the list:\n";
   for ($i=0;$i<scalar(@newarray);$i++) {
      print " element ",$i+1," = [$newarray[$i-1]]\n";
   }
   print "\nThe old and new arrays ";
   if ("@oldarray" eq "@newarray")
       {print "match:\n"}
   else
      {print "DON'T match:\n"};
   print "   old:>@oldarray<\n",
         "   new:>@newarray<\n";
Copy code to clipboard

This code produces the following output:

   This list is from property CurrentList:
   There are 4 elements in the list:
     element 1 = [Just a small list.]
     element 2 = [1]
     element 3 = []
     element 4 = [2.78]
   
   The old and new arrays match:
      old:>1  2.78 Just a small list.<
      new:>1  2.78 Just a small list.<
Copy code to clipboard
Example 3: Testing List Capacity

It is important to make sure that a Cache %List variable can contain the entire Perl array. The following code creates a Perl array that is too large, and attempts to store it in the CurrentList property.

# Create a large array and print array information.
   $longitem = "1022 character element".(1234567890 x 100);
   @array =("This array is too long.");
   $cache_list_size = length($array[0]);
   for ($i=0;$i<33;$i++) {
        push(@array,$longitem);
        $cache_list_size += length($longitem);
   };
   print "\n\nNow for a HUGE list:\n";
   print "Total bytes required by Cache' list: more than $cache_list_size\n";
   print "There are ",scalar(@array)," elements in the ingoing list.\n\n";

# Check to see if the array will fit.
   $bool =  $listobj->TestList(\@array);
   print "TestList() reports that the array ";
   if ($bool) {print "is OK, and has $bool elements.\n";}
   else {print "will be damaged by the conversion.\n"};

# Pass the array to Cache', get it back, and display the results
   $listobj->set("CurrentList",\@array);
   $badarrayref = $listobj->get("CurrentList");
   @badarray = @$badarrayref;

   print "There are ",scalar(@badarray)," elements in the returned list:\n";
   for ($i=0;$i<scalar(@badarray);$i++) {
      $line = $badarray[$i];
      # long elements are shortened for readability.
      if (length($line)> 1000) {substr($line,10,980) = "..."};
      print "   element ",$i+1," = [$line]\n";
   }
Copy code to clipboard

The printout shortens undamaged sections of the long elements to make the output more readable. The following output is produced on a unicode system:

   Now for a HUGE list:
   Total bytes required by Cache' list: more than 33749
   There are 34 elements in the ingoing list.
   
   TestList() reports that the array will be damaged by the conversion.
   There are 17 elements in the returned list:
      element 1 = [This array is too long.]
      element 2 = [1022 chara...90123456789012345678901234567890]
      element 3 = [1022 chara...90123456789012345678901234567890]
      element 4 = [1022 chara...90123456789012345678901234567890]
      element 5 = [1022 chara...90123456789012345678901234567890]
      element 6 = [1022 chara...90123456789012345678901234567890]
      element 7 = [1022 chara...90123456789012345678901234567890]
      element 8 = [1022 chara...90123456789012345678901234567890]
      element 9 = [1022 chara...90123456789012345678901234567890]
      element 10 = [1022 chara...90123456789012345678901234567890]
      element 11 = [1022 chara...90123456789012345678901234567890]
      element 12 = [1022 chara...90123456789012345678901234567890]
      element 13 = [1022 chara...90123456789012345678901234567890]
      element 14 = [1022 chara...90123456789012345678901234567890]
      element 15 = [1022 chara...90123456789012345678901234567890]
      element 16 = [1022 chara...90123456789012345678901234567890]
      element 17 = [1022 chara...90123456ray is too long.ï´√ȇ1022 c]
Copy code to clipboard

The damaged list contains only 17 of the original 34 elements, and element 17 is corrupted.

Using Relationships

Relationships are supported through the relationship object and its methods.

The following example generates a report by using the one/many relationship between the $company object and a set of $employee objects. The relationship object $emp_relationship allows the code to access all $employee objects associated with the $company object:

   $company = $database->openid("Sample.Company", "1", -1, 0);
   $emp_relationship = $company->get("Employees");
   $index=undef;
   do {
      $employee = $emp_relationship->run_obj_method("GetNext",$index);
      # "GetNext" sets $index to the next valid index, or to undef if
      # there are no more records.
      if ($index) {
         $name = $employee->get("Name");
         $title = $employee->get("Title");
         $company = $employee->get("Company");
         $compname = $company->get("Name");
         $SSN = $employee->get("SSN");
         print "index=$index employee name=$name SSN=$SSN ",
               "title=$title companyname=$compname\n";
      };
   } while ($index);
Copy code to clipboard

The following code creates a new employee record, adds it to the relationship, and automatically saves the employee information when it saves $company.

   $new_employee = $database->create_new("Sample.Employee","");
   $new_employee->set("Name",$name);
   $new_employee->set("Title",$title);
   $new_employee->set("SSN",$SSN);
   $emp_relationship->run_obj_method("Insert", $new_employee);
   $company->run_obj_method("%Save"); 
Copy code to clipboard

Using Queries

The basic procedure for running a query is as follows:

  • Create the query object

       $query = $database->alloc_query()
    Copy code to clipboard

    where $database is an Intersys::PERLBIND::Database object and $query is an Intersys::PERLBIND::Query object.

  • Prepare the query

    An SQL query uses the prepare() method:

       $query->prepare($sql_query, $sqlcode)
    Copy code to clipboard

    where $sql_query is a string containing the query to be executed.

    A Caché class query uses the prepare_class() method:

       $query->prepare_class($class_name, $query_name, $sqlcode)
    Copy code to clipboard
  • Assign parameter values

       $query->set_par($idx, $val)
    Copy code to clipboard

    The set_par() method assigns value $val to parameter $idx. The value of an existing parameter can be changed by calling set_par() again with the new value. The Query class provides several methods that return information about an existing parameter.

  • Execute the query

       $query->execute($sqlcode)
    Copy code to clipboard

    The execute() method generates a result set using any parameters defined by calls to set_par().

  • Fetch a row of data

       @data_row = $query->fetch($sqlcode)
    Copy code to clipboard

    Each call to the fetch() method retrieves a row of data from the result set and returns it as a list. When there is no more data to be fetched, it returns an empty list. The Query class provides several methods that return information about the columns in a row.

    Here is a simple SQL query that retrieves data from Sample.Person:

       # Allocate, prepare, set a parameter, and get a result set:
       $query = $database->alloc_query();
       $sql_query = 
          "SELECT ID, Name, DOB, SSN FROM Sample.Person
          ~WHERE Name %STARTSWITH ?";
       $sqlcode=0;
       $query->prepare($sql_query, $sqlcode);
       $query->set_par(1,"A");
       $query->execute($sqlcode);
    
       # Fetch each row in the result set, and print the
       # name and value of each column in a row: 
       $rownum = 1;
       while (@data_row = $query->fetch($sqlcode)) {
          print "Row $rownum ===================\n";
          $colnum = 1;
          foreach $col_data (@data_row) {
             $col_name = $query->col_name($colnum);
             print " $col_name: $col_data\n";
             $colnum++;
          }
          $rownum++
       }
    Copy code to clipboard

For more information on the Intersys::PERLBIND::Query class, see Queries in the Perl Client Class Reference chapter. For information about queries in Caché, see Defining and Using Class Queries in Using Caché Objects.

Using %Binary Data

The Perl binding uses the Perl pack() and unpack() functions to convert data between a Caché %Binary and a Perl array of ords. Each byte of the Caché binary data is represented in Perl as an integer between 0 and 255.

The examples in this section assume the following Caché class:

   Class Sample.Bin Extends %Persistent
   {
      Property B As %Binary;

      Method GetBinary() As %Binary {
         q "hello"}

      Method SetBinary(PerlBin As %Binary) {
         s ^foobar=PerlBin}
   }
Copy code to clipboard

The class uses %Binary data in a variety of ways: as a property value, a method return value, a method argument, and a global variable. The following code transfers binary data back and forth between Caché and Perl several times. The Perl application makes a change in the data each time.

The first input is a method result. The GetBinary() method returns the %Binary value "hello". The value is unpacked and the resulting array is printed out:

   $binobj = $database->openid("Sample.Bin",1,-1,0);
   $B_packed = $binobj->run_obj_method("GetBinary");
   @B_unpacked = unpack("c*",$B_packed ); # "c*" is the template for an ord
   foreach $c (@B_unpacked) {
      # "%c" turns the ord value $c into a character
      printf "[%c]",$c
   }
   print "\n";
Copy code to clipboard

The first line of output looks like this:

   [h][e][l][l][o]
Copy code to clipboard

Now the program changes the first byte to a "j" and repacks the array. The packed value is stored in Caché %Binary property B, and the altered Caché object is saved:

   $B_unpacked[0] = ord("j");
   $B_packed = pack("c*",@B_unpacked);
   $binobj->set("B",$B_packed);
   $binobj->run_obj_method("%Save");
Copy code to clipboard

The second input is a property value. The %Binary value "jello" is retrieved from property B and unpacked. The program changes the value again, this time by adding a new element to the end of the array:

   $B_packed = $binobj->get("B");
   @B_unpacked = unpack("c*",$B_packed ); # "c*" is the template for an ord
   push @B_unpacked, ord("!");
   foreach $c (@B_unpacked) {
      printf "[%c]",$c
   }
   print "\n";
   };
Copy code to clipboard

Combined with the previous line, the output now look like this:

   [h][e][l][l][o]
   [j][e][l][l][o][!]
Copy code to clipboard

Finally, the program packs the array again and passes it as an argument to the SetBinary() method, which stores it in Caché global variable ^foobar:

   $B_packed = pack("c*",@B_unpacked);
   $binobj->run_obj_method("SetBinary",$B_packed); 
Copy code to clipboard

Handling Exceptions

The Perl binding uses Perl exceptions to return errors from the C binding and elsewhere.

Here are some examples of using Perl exceptions:

   eval {
      $answer = $variant2->run_obj_method("PassLastByRefAdd17","10","goodbye");
   };
   if ($@) {
      print "Perl exception $@\n";
   }

   # Attempt to open a nonexistent id
   eval {
      $causeException = $database2->openid("NonExistent", "1", -1, 0);
   };
   if ($@) {
      print "Perl exception $@\n";
   }
Copy code to clipboard

Handling %Status Return Values

When a method declares a return type of %Status, the status value is not returned. Instead, an exception is thrown. For example, assume that we want to call the following Caché method that returns %Status:

   Class User.PerlStatus Extends %Persistent{
      ClassMethod MyStatus() as %Status
      {
         q $$$ERROR(-137,"bad fine structure constant")
      }
   }
Copy code to clipboard

The following Perl binding program calls the MyStatus() method, captures the exception, and prints the return status value:

   # TestStatus.pl: illustrate handling a bad status return from COS 

   use Intersys::PERLBIND; 
   my $user="_SYSTEM"; 
   my $password="SYS"; 
   my $url = "localhost[1972]:USER";
   eval { 
      $conn = Intersys::PERLBIND::Connection->new($url,$user,$password,0);
      $database = Intersys::PERLBIND::Database->new($conn);
      $status=$database->run_class_method("User.PerlStatus", "MyStatus");
      # exception is thrown before we get here
      print "status=$status\n"; 
   }; 

   if ($@) { 
      print "Caught exception: $@\n"; 
   } else { 
      print "\nSample finished running\n"; 
   } 
Copy code to clipboard

Error Reporting

When processing an argument or a return value, error messages from the C binding are specially formatted by the Perl binding layer. This information can be used by InterSystems WRC to help diagnose the problem.

Here is a sample error message:

   file=PERLBIND.xs line=71 err=-1 message=cbind_variant_set_buf()
   cpp_type=4 var.cpp_type=-1 var.obj.oref=1784835886
   class_name=%Library.RelationshipObject mtd_name=GetNext argnum=0
Copy code to clipboard

The error message components are:

message
meaning
file=PERLBIND.xs
file where the failure occurred.
line=71
line number in the file.
err=-1
return code from the C binding.
message= cbind_variant_set_buf()
C binding error message.
cpp_type=4
cpp type of the method argument or return type.
var.cpp_type=-1
variant cpp type.
var.obj.oref=1784835886
variant oref.
class_name= %Library.RelationshipObject
class name of the object on which the method is invoked.
mtd_name=GetNext
method name.
argnum=0
argument number. 0 is the first argument and -1 indicates a return value.

Perl Binding Constraints and Limitations

The Perl binding imposes the following limitations, which are usually related to differences in the way that Perl and Caché handle certain datatypes:

  • The Perl binding inherits the limitations of ObjectScript methods and datatypes. For example, if your Caché system limits %String to 32K, a Perl program would fail if it attempted to write more than 32K to a Caché character stream.

  • Caché and Perl differ on the numeric ranges of fundamental data types and on parameters such as the range of the mantissa and the exponent. This may cause problems when your program manipulates very large numbers (for example, comparing integers with greater than about 15 digits). A workaround is to fetch such data from Caché as %Binary strings.

  • When working with both 32-bit and 64-bit systems, it is important to remember that numeric processing may be affected by 32-bit limitations. On a 32-bit system, an integer variable is limited to 32 bits, and a decimal must fit both signficand and exponent into 32 bits as signed integers.

  • A %Status parameter cannot be passed by reference (also see Handling %Status Return Values). A workaround is to pass the value as an integer.

  • Some Caché library methods receive and return Caché local arrays as parameters passed by reference. Caché language bindings do not support methods that have local array parameters. A workaround is to write Caché wrapper methods that process the local arrays on the Caché side.

  • A connection will be lost if the Perl code forks to a child process (or Windows thread). For example, the following code fragment forks a no-op child process, after which the connection is lost by the main program. The connection reference is copied for the child process and closed when the child exits.

       my $pid = fork();
       if ( !defined( $pid)) {
          die( "fork() failed\n");
       }
       if ( $pid == 0) { # child
          print( "child: calling exit()\n");
          exit( 0);
       } else { # parent
          waitpid( $pid, 0); # wait for the child to exit
       }
       my $ret = $db->run_class_method( "%SYSTEM.OBJ", "Version", ());
    
    Copy code to clipboard