Input/Output
As we stated in the previous section, all Core Perl constructions may be brought into use in PerlNET. Input/output issues are not an exception.
Performing Output
Instead of using a long call to the WriteLine method of the Console class, we can write
print "Hello from Perl!\n";
and we will get the same result as if had written
Console->WriteLine("Hello from Perl!");
The reason we use the Console class rather then Core Perl print is to demonstrate the .NET concepts on simple examples and to show the .NET way to do things. You may combine Core Perl and .NET statements to perform output. However, you may run into buffering problems when running the program in some environments, so that your program output would not be in the original order that you meant when designing the program. This may occur when you test your Managed Exe Perl project in Visual Studio running it with Ctrl-F5 (we present the Visual Studio description in Appendix A). The reason for this is that the .NET methods and Core Perl functions use different buffers for output and you do not control the order in which these buffers are flushed. To prevent this, you should add the following statement, which instructs Perl not to buffer the output, at the beginning of your program:
$| = 1;
Examine the IO\ Buffering sample.
# # Buffering.pl # use strict; use namespace "System"; use PerlNET qw(AUTOCALL); $| = 1; Console->WriteLine("1"); print "2\n"; Console->WriteLine("3");
If you comment the $| = 1 statement, then the output in the Visual Studio Run window will look like what follows.
1 3 2
This is definitely not the order of printing we meant. If you uncomment the assignment, this will restore the original output order.
Getting Input
Most applications involve user interaction. Core Perl offers a simple way to treat user input:
<STDIN>;
As you probably guessed, the .NET SDK introduces several methods to treat user input. We will show how to take benefit of these methods.
You may implement a simple text-based user interface with the ReadLine method of the Console class. This method does not take any parameters and returns the string that it reads from the standard input device.
Before we present a sample program, we should explain another feature of the WriteLine method: placeholders. When performing output, often you need to include variables or expressions whose values are known only at run-time. The WriteLine method reserves a place for the expression in the output string. For each expression, there are placeholders {0}, {1}, and so on. The expressions should be placed after closing quotes and should be delimited by commas. Here is the simple example.
my $x = 3; Console->WriteLine("x={0};x+1={1};x^2={2}",$x,$x+1,$x**2);
The output is
x=3;x+1=4;x^2=9
The following sample takes as input float number x and calculates its exponent. We use the static method Exp of the Math class. Our program demonstrates two ways of calculating the exponent.
# # Exp.pl # use namespace "System"; use PerlNET qw(AUTOCALL); Console->WriteLine("Please enter a number:"); # Get input from user my $x = Console->ReadLine(); Console->WriteLine("1)exp({0}) = {1}", $x, Math->Exp($x)); Console->WriteLine("2)exp({0}) = {1}", $x, Math->E ** $x);
You may find the above program in the IO\Exp folder. To compile the program type
plc Exp.pl
If you did not make any syntax mistakes, the compilation should accomplish successfully. Now run Exp.exe. Enter some number when the program asks you to, and examine the response. You should get an error message:
System.ApplicationException: Can't locate public static method Exp(System.String) for System.Math.
The problem is caused by the Math->Exp($x) statement. If we comment the whole line, compile, and run again, there should not be any error messages. The output may look as shown below.
Please enter a number: 1 2)exp(1) = 2.71828182845905
By now, you should know how to fix the first WriteLine statement to get a clean execution. The ReadLine method of the Console class returns System.String that PerlNET runtime module delivers to our program as a Perl string scalar. The solution is to clear the string representation. We do it by passing the $x+0 value to the Exp method.
Console->WriteLine("1)exp({0}) = {1}", $x, Math->Exp($x+0));
We saved the correct version of the program in IO\ExpFix. Now, after rebuilding and running the exponent program again, you should get no error messages.
Please enter a number: 2.5 1)exp(2.5) = 12.1824939607035 2)exp(2.5) = 12.1824939607035