Calling Methods

We can access .NET methods through the standard Perl method-calling syntax. We pass arguments to methods the same way as we do it in Core Perl:

$foo->Method(@args);

Look at the following fragment:

my $obj = StringBuilder->new("How");
$obj->Append(" Are You?");
print $obj;

After constructing an object and storing a reference to it in $obj, we call the Append method, passing to it " Are you?" string as an argument. The method will append this string to the "How" string and the last statement will print

How Are You?

Every .NET class inherits the ToString method from System.Object. The class either overrides this method or uses the base class version of the method. If we call ToString on the StringBuilder object, then it will return the encapsulated string. PerlNET automatically invokes the ToString method on any object reference that is used in string context. Hence, the last statement in the above fragment works correctly and we do not have to perform any conversions on $obj.

Static Methods

If you plan to work with static methods in your PerlNET application, you have two options to invoke them:

  • Using PerlNET::call

  • Arrow syntax with AUTOCALL

PERLNET::CALL

When working with the call helper function, as its first argument you pass a method to invoke as a string (you have to prefix the method with name of the class that exposes this static method). The second argument of call is an argument list that you pass to your static method. You may enumerate all the arguments, delimiting them with commas. For example, here is how we may obtain the maximum of two numbers, 3 and 5. Though the answer is obvious for us, we would like to check if the same is true for the Max method of the Math class.

use namespace "System";

my $bigger = PerlNET::call("Math.Max", 3, 5);
print $bigger;

Another way to pass arguments to the static method when using call is to build a Perl array (list) of them.

use namespace "System";

my @args = (3, 5);
my $bigger = PerlNET::call("Math.Max", @args);
print $bigger;

When your static method takes no parameters, like Console.ReadLine, then you should supply an empty arguments list in one of the forms of your choice.

use namespace "System";
. . .
PerlNET::call("Console.ReadLine", ());  # Right
PerlNET::call("Console.ReadLine", );    # Right
PerlNET::call("Console.ReadLine");      # Right
PerlNET::call("Console.ReadLine", "");  # Wrong!

AUTOCALL

The second alternative that PerlNET offers is using standard Perl method-calling syntax (arrow syntax) on a .NET class name. For example,

Math->Max(3, 5);

To use the above form, you should import AUTOCALL from the PerlNET module:

use PerlNET qw(AUTOCALL);

This instructs Perl to retry all the calls as .NET calls, for which no Perl method was found. Supplying parameters in such calls is the same as in all .NET calls. You may either delimit your parameters with comma or pass a list. In case of methods such as ReadLine, just leave the brackets empty or pass an empty list:

use PerlNET qw(AUTOCALL);
Console->ReadLine();

STATIC METHODS SUMMARY

Summarizing our discussion about the static methods, we recommend the second alternative, using AUTOCALL, which will result in more readable code, and the inefficiency of retrying the calls is insignificant. Besides, it makes programming in PerlNET an even more pleasant experience.

Marshalling Types

Whenever you invoke a method—either static or non-static—and supply some arguments, you have to make sure that these arguments are of the correct type. This means that if some class defines a method that expects a double value, you cannot pass a string to it, unlike in the case of Core Perl subroutines.

my $a = Math->Exp("1.5");   # Wrong! .NET call
my $b = Math->Exp(1.5);     # Correct - .NET call
my $c = exp(1.5);           # Correct – Core Perl
my $d = exp("1.5");         # Correct – Core Perl

To assure that we supply arguments with the correct type to a .NET method, you should use special cast functions imported from the PerlNET module. They translate Perl scalars into all the basic .NET value types. As a result, the translated value represents a corresponding .NET value type object. Table 10-1 shows the possible casting operations between Perl and .NET.

Table 10-1. Value Types Conversion in PerlNET
SystemPerlNET
Booleanbool
Charchar
SBytesbyte
Int16short
Int32int
Int64long
Bytebyte
UInt16ushort
UInt32uint
UInt64ulong
Singlefloat
Doubledouble
Decimaldecimal

For example, PerlNET::decimal produces a System.Decimal value. Note that the PerlNET cast functions' names are the same as corresponding C# data types.

PerlNET automatically converts all value types into strings as needed and also implements autoincrement and autodecrement operators for them, covering the whole valid value range. The wraparound behavior is the same as of the underlying .NET types.

my $byte = PerlNET::byte(255);
++$byte;

yields the same result as

my $byte = PerlNET::byte(0);

Normal arithmetic operations, however, will convert the .NET value types into Perl integers or floating-point numbers. That means that the result is no longer a .NET value type, and that values exceeding 32-bit integers (for long, ulong, and decimal types) may not be converted correctly. Numeric comparisons for these three types will also not work.

use PerlNET qw(uint);
...
my $word = uint(42);
$word += 7;

# need to convert back to System.UInt32 as $word is now
# just a Perl int
$obj->Method( uint($word) );

Note that you will override the built-in int() function if you import PerlNET::int() into your program.

use PerlNET qw(int);
...
# use CORE::int() to call builtin Perl int() function
# my $int = CORE::int($val*1.68);

With the help of these cast functions, we may pass to .NET methods even variables or constants that store Perl strings.

my $s = "1.5";
my $res = Math->Exp(PerlNET::double($s));     # Correct!
my $res2 = Math->Exp(PerlNET::double("1.5")); # Correct!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.253.62