⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch4.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
a function, an asterisk for any type, and a semicolon to indicate

that all other parameters are optional.

<P>

Now, let's look at the <TT><FONT FACE="Courier">lastMovingAverage</FONT></TT>

function declaration, which specifies two integers in the front

followed by an array. The way the arguments are used in the function

is to assign a value to each of the two scalars, <TT><FONT FACE="Courier">$count</FONT></TT>

and <TT><FONT FACE="Courier">$number</FONT></TT>, whereas everything

else is sent to the array. Look at the function <TT><FONT FACE="Courier">getMovingAverage()</FONT></TT>

to see how two arrays are passed in order to get the moving average

on a list of values.

<P>

The way to call the <TT><FONT FACE="Courier">getMovingAverage</FONT></TT>

function is shown in Listing 4.5.

<HR>

<BLOCKQUOTE>

<B>Listing 4.5. Using the moving average function.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl -w<BR>

&nbsp;2 <BR>

&nbsp;3 push(@Inc,'pwd');

<BR>

&nbsp;4 use Finance;<BR>

&nbsp;5 <BR>

&nbsp;6 @values = ( 12,22,23,24,21,23,24,23,23,21,29,27,26,28

);<BR>

&nbsp;7 @mv = (0);<BR>

&nbsp;8 $size = scalar(@values);<BR>

&nbsp;9 print &quot;\n Values

to work with = { @values } \n&quot;;<BR>

10 print &quot; Number of values = $size \n&quot;;<BR>

11 <BR>

12 # ----------------------------------------------------------------

<BR>

13 # Calculate the average of the above function<BR>

14 # ----------------------------------------------------------------

<BR>

15 $ave = Finance::getLastAverage(5,$size,@values);<BR>

16 print &quot;\n Average of last 5 days = $ave \n&quot;;<BR>

17 <BR>

18 Finance::getMovingAve(5,$size,@values,@mv);<BR>

19 print &quot;\n Moving Average with 5 days window = \n { @mv

} \n&quot;;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Here's the output from Listing 4.5:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">Values to work with = { 12 22 23 24 21

23 24 23 23 21 29 27 26 28 }<BR>

Number of values = 14<BR>

<BR>

Average of last 5 days = 26.2<BR>

<BR>

Moving Average with 5 days window =<BR>

{ 0 0 0 0 0 19.4 21.8 22 22 21.4 23 23.8 24.2 25.2 }</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">getMovingAverage()</FONT></TT> function

takes two scalars and then two references to arrays as scalars.

Within the function, the two scalars to the arrays are dereferenced

for use as numeric arrays. The returned set of values is inserted

in the area passed in as the second reference. Had the input parameters

not been specified with <TT><FONT FACE="Courier">\@</FONT></TT>

for each referenced array, the <TT><FONT FACE="Courier">$movingAve</FONT></TT>

array reference would have been empty and would have caused errors

at runtime. In other words, the following declaration is not correct:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">sub getMovingAve($$@@)</FONT></TT>

</BLOCKQUOTE>

<P>

The resulting spew of error messages from a bad function prototype

is as follows:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">Use of uninitialized value at Finance.pm

line 128.<BR>

Use of uninitialized value at Finance.pm line 128.<BR>

Use of uninitialized value at Finance.pm line 128.<BR>

Use of uninitialized value at Finance.pm line 128.<BR>

Use of uninitialized value at Finance.pm line 128.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

Use of uninitialized value at Finance.pm line 133.<BR>

Use of uninitialized value at Finance.pm line 135.<BR>

<BR>

Values to work with = { 12 22 23 24 21 23 24 23 23 21 29 27 26

28 }<BR>

Number of values = 14<BR>

<BR>

Average of last 5 days = 26.2<BR>

<BR>

Moving Average with 5 days window =<BR>

{ 0 }</FONT></TT>

</BLOCKQUOTE>

<P>

This is obviously not the correct output. Therefore, it's critical

that you pass by reference when sending more than one array.

<P>

Global variables for use within the package can also be declared.

Look at the following segment of code from the <TT><FONT FACE="Courier">Finance.pm</FONT></TT>

module to see what the default value of the <TT><FONT FACE="Courier">Interest</FONT></TT>

variable would be if nothing was specified in the input. (The

current module requires the interest to be passed in, but you

can change this.)

<P>

Here's a little snippet of code that can be added to the end of

the program shown in Listing 4.5 to add the ability to set interest

rates. 

<BLOCKQUOTE>

<TT><FONT FACE="Courier">20 local $defaultInterest = 5.0;<BR>

21 sub Finance::SetInterest($) {<BR>

22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

my $rate = shift(@_);<BR>

23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

$rate *= -1 if ($rate &lt; 0); <BR>

24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

$defaultInterest = $rate;<BR>

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

printf &quot;\n \$defaultInterest = $rate&quot;;<BR>

26 }</FONT></TT>

</BLOCKQUOTE>

<P>

The local variable <TT><FONT FACE="Courier">$defaultInterest</FONT></TT>

is declared in line 20. The subroutine <TT><FONT FACE="Courier">SetInterest</FONT></TT>

to modify the rate is declared in lines 21 through 26. The <TT><FONT FACE="Courier">$rate</FONT></TT>

variable uses the values passed into the subroutine and simply

assigns a positive value for it. You can always add more error

checking if necessary. 

<P>

To access the <TT><FONT FACE="Courier">defaultInterest</FONT></TT>

variable's value, you could define either a subroutine that returns

the value or refer to the value directly with a call to the following

in your application program:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$Finance::defaultInterest;</FONT></TT>

</BLOCKQUOTE>

<H3><A NAME="ReturnedValuesfromSubroutinesinaPa">Returned Values

from Subroutines in a Package</A></H3>

<P>

The variable holding the return value from the module function

is declared as <TT><FONT FACE="Courier">my variable</FONT></TT>.

The scope of this variable is within the curly braces of the function

only. When the called subroutine returns, the reference to <TT><FONT FACE="Courier">my

variable</FONT></TT> is returned. If the calling program uses

this returned reference somewhere, the link counter on the variable

is not zero; therefore, the storage area containing the returned

values is not freed to the memory pool. Thus, the function that

declares

<BLOCKQUOTE>

<TT><FONT FACE="Courier">my $pv</FONT></TT>

</BLOCKQUOTE>

<P>

and then later returns the value of <TT><FONT FACE="Courier">$pv</FONT></TT>

returns a reference to the value stored at that location. If the

calling routine performs a call like this one:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">Finance::FVofAnnuity($monthly,$rate,$time);</FONT></TT>

</BLOCKQUOTE>

<P>

there is no variable specified here into which Perl stores the

returned reference; therefore, any returned value (or a list of

values) is destroyed. Instead, the call with the returned value

assigned to a local variable, such as this one:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$fv = Finance::FVofAnnuity($monthly,$rate,$time);</FONT></TT>

</BLOCKQUOTE>

<P>

maintains the variable with the value. Consider the example shown

in Listing 4.6, which manipulates values returned by functions.

<HR>

<BLOCKQUOTE>

<B>Listing 4.6. Sample usage of the </B><TT><B><FONT FACE="Courier">my</FONT></B></TT><B>

function.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl -w<BR>

&nbsp;2 <BR>

&nbsp;3 push(@Inc,'pwd');

<BR>

&nbsp;4 use Finance;<BR>

&nbsp;5 <BR>

&nbsp;6 $monthly = 400;<BR>

&nbsp;7 $rate = 0.2;&nbsp;&nbsp;&nbsp;#

i.e. 6 % APR<BR>

&nbsp;8 $time = 36;&nbsp;&nbsp;&nbsp;&nbsp;# in months<BR>

&nbsp;9 <BR>

10 print &quot;\n# ------------------------------------------------&quot;;

<BR>

11 $fv = Finance::FVofAnnuity($monthly,$rate,$time);<BR>

12 printf &quot;\n For a monthly %8.2f at a rate of %%%6.2f for

%d periods&quot;,<BR>

13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

$monthly, $rate, $time;<BR>

14 printf &quot;\n you get a future value of %8.2f &quot;, $fv;

<BR>

15 <BR>

16 $fv *= 1.1; # allow 10 % gain in the house value.<BR>

17 <BR>

18 $mo = Finance::AnnuityOfFV($fv,$rate,$time);<BR>

19 <BR>

20 printf &quot;\n To get 10 percent more at the end, i.e. %8.2f&quot;,$fv;

<BR>

21 printf &quot;\n you need a monthly payment value of %8.2f&quot;,$mo,$fv;

<BR>

22 <BR>

23 print &quot;\n# ------------------------------------------------

\n&quot;;</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Here is sample input and output for this function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$ <B>testme<BR>

</B># ------------------------------------------------<BR>

&nbsp;For a monthly&nbsp;&nbsp;&nbsp;400.00

at a rate of %&nbsp;&nbsp;0.20 for 36 periods<BR>

&nbsp;you get a future value of 1415603.75<BR>

&nbsp;To get 10 percent more

at the end, i.e. 1557164.12<BR>

&nbsp;you need a monthly payment value of&nbsp;&nbsp;&nbsp;440.00

<BR>

# ------------------------------------------------</FONT></TT>

</BLOCKQUOTE>

<H2><A NAME="MultipleInheritance"><FONT SIZE=5 COLOR=#FF0000>Multiple

Inheritance</FONT></A></H2>

<P>

Modules implement classes in a Perl program that uses the object-oriented

features of Perl. Included in object-oriented features is the

concept of <I>inheritance</I>. (You'll learn more on the object-oriented

features of Perl in <A HREF="ch5.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch5.htm" >Chapter 5</A>, &quot;Object-Oriented

Programming in Perl.&quot;) Inheritance means the process with

which a module inherits the functions from its base classes. A

module that is nested within another module inherits its parent

modules' functions. So inheritance in Perl is accomplished with

the <TT><FONT FACE="Courier">::</FONT></TT> construct. Here's

the basic syntax:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">SuperClass::NextSubClass:: ... ::ThisClass.</FONT></TT>

</BLOCKQUOTE>

<P>

The file for these is stored in <TT><FONT FACE="Courier">./SuperClass/NextSubClass/&#133;</FONT></TT>.

Each double colon indicates a lower-level directory in which to

look for the module. Each module, in turn, declares itself as

a package with statements like the following:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">package SuperClass::NextSubClass;<BR>

package SuperClass::NextSubClass::EvenLower;</FONT></TT>

</BLOCKQUOTE>

<P>

For example, say that you really want to create a <TT><FONT FACE="Courier">Money</FONT></TT>

class with two subclasses, <TT><FONT FACE="Courier">Stocks</FONT></TT>

and <TT><FONT FACE="Courier">Finance</FONT></TT>. Here's how to

structure the hierarchy, assuming you are in the <TT><FONT FACE="Courier">/usr/lib/perl5</FONT></TT>

directory:

<OL>

<LI>Create a <TT><FONT FACE="Courier">Mone

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -