Wrapping for the Typoifier module is pretty straight-forward. Simply choose methods and properties to expose and add entries for them in the interface definition, supplying property, method argument, and return value types. However, you may often need to perform a workaround in the wrapper component to make it functional. The following are examples of special wrapping cases that require a small amount of code to handle specific problems.
Returning a List
When a wrapped module contains a Perl subroutine that returns a list (a Perl array or Perl hash), it would be nice to automatically convert this Core Perl structure into a .NET array of the correct type. Fortunately, PerlNET provides the wantarray! method modifier, which does exactly that:
wantarray! str SomeWords();
. . .
# Subroutine implementation in some module
return qw(Computer Mouse Printer);
Many Core Perl modules provide class methods and you don't have to instantiate an object to invoke them. In .NET, such methods are static, so when exposing them to .NET, apply the static modifier inside the interface definition. This tells PerlNET not to supply a package as the first argument to those methods. For example, the wrapper for the Roman module (see Listing 2
) exposes only static methods.
Constructor Name Collision
As I mentioned earlier, a wrapper class must share its name with the package of the module it wraps. This restriction can sometimes cause name collisions. For instance, the Roman module provides a procedural interface for converting Roman numbers into Arabic and vice versa. One of its subroutines is called Roman. It accepts an Arabic number and returns the corresponding Roman number in all capital letters. Using the standard wrapping naming convention here results in this entry for the Roman subroutine in the interface definition:
static str Roman(int arabic);
Because the package name is also Roman, PerlNET treats this entry as a class constructor despite the str type for return value and doesn't readdress the calls to the Roman subroutine. To avoid this, create a new method called RomanFwd in the interface definition. This method forwards the calls to the original Roman method. Listing 2
shows the code for the wrapper. Next, provide the implementation for this method, and call the Roman subroutine. The Roman module also has a roman method, but this doesn't create a name collision because, like Perl, PerlNET and .NET are case-sensitive.
Property Methods Name Collisions
Another problem arises when you wrap a module using methods with the prefixes get, set, get_, set_. PerlNET treats get_XXX (getXXX) and set_XXX (setXXX) methods as accessors and mutators of an XXX property respectively. To treat such subroutines as regular methods, create new methods that forward the calls to the original subroutines (see Listing 3). Create a PerlNET wrapper for the Text::Structured module that exposes two problematic methods, get_text_at and get_text_re. The client program invokes these methods using their new names: Get_text_at and Get_text_re.