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

📄 ch25.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<BLOCKQUOTE>

<TT><FONT FACE="Courier">SV** av_store(AV *ptr, I32 key, SV* item);

<BR>

</FONT></TT>Stores the value of the item at the offset.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void av_clear(AV *ptr);<BR>

</FONT></TT>Sets all items to zero but does not destroy the array

in <TT><FONT FACE="Courier">*ptr</FONT></TT>.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void av_undef(AV *ptr);<BR>

</FONT></TT>Removes the array and all its items.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void av_extend(AV *ptr, I32 size);<BR>

</FONT></TT>Resizes the array to the maximum of the current size

or the passed size.

</BLOCKQUOTE>

<H2><A NAME="HashFunctions"><B><FONT SIZE=5 COLOR=#FF0000>Hash

Functions</FONT></B></A></H2>

<P>

Hash variables have <TT><FONT FACE="Courier">HV</FONT></TT> in

their names and are created in a manner similar to creating array

functions. To create an <TT><FONT FACE="Courier">HV</FONT></TT>

type, you call this function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">HV*&nbsp;&nbsp;newHV();</FONT></TT>

</BLOCKQUOTE>

<P>

Here's how to use an existing hash function and refer to it by

name:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">HV*&nbsp;&nbsp;perl_get_hv(&quot;myHash&quot;,

FALSE);</FONT></TT>

</BLOCKQUOTE>

<P>

The function returns <TT><FONT FACE="Courier">NULL</FONT></TT>

if the variable does not exist. If the hash does not already exist

and you want Perl to create the variable for you, use:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">HV*&nbsp;&nbsp;perl_get_hv(&quot;myHash&quot;,

TRUE);</FONT></TT>

</BLOCKQUOTE>

<P>

As with the <TT><FONT FACE="Courier">AV</FONT></TT> type, you

can perform the following functions on an <TT><FONT FACE="Courier">HV</FONT></TT>

type of variable:

<UL>

<LI><TT><FONT FACE="Courier">SV** hv_store(HV* hptr,</FONT></TT>

<LI><TT><FONT FACE="Courier">char* key&nbsp;&nbsp;</FONT></TT>The

key of the hash item

<LI><TT><FONT FACE="Courier">U32 klen,&nbsp;&nbsp;</FONT></TT>The

length of the key

<LI><TT><FONT FACE="Courier">SV* val,&nbsp;&nbsp;&nbsp;</FONT></TT>The

scalar to insert

<LI><TT><FONT FACE="Courier">U32 hash)&nbsp;&nbsp;</FONT></TT>Zero

unless you compute the hash function yourself

<LI><TT><FONT FACE="Courier">SV**&nbsp;&nbsp;hv_fetch(HV* hptr,</FONT></TT>

<LI><TT><FONT FACE="Courier">char* keyq </FONT></TT>The key of

the hash

<LI><TT><FONT FACE="Courier">U32 klen&nbsp;&nbsp;&nbsp;</FONT></TT>The

length of the key

<LI><TT><FONT FACE="Courier">I32 lval)&nbsp;&nbsp;</FONT></TT>Its

value

</UL>

<P>

Check the file <TT><FONT FACE="Courier">hv.c</FONT></TT> in your

Perl distribution for the function source file for details about

how the hash function is defined. Both of the previous functions

return pointers to pointers. The return value from either function

will be <TT><FONT FACE="Courier">NULL</FONT></TT>.

<P>

The following functions are defined in the source file:

<BLOCKQUOTE>

bool hv_exists(HV*, char* key, U32 klen);<BR>

This function returns TRUE or FALSE.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">SV* hv_delete(HV*, char* key, U32 klen,

I32 flags);<BR>

</FONT></TT>This function deletes the item, if it exists, at the

specified key.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void hv_clear(HV*);<BR>

</FONT></TT>This function leaves the hash but removes all its

items.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void hv_undef(HV*);<BR>

</FONT></TT>This function removes the hash and its items.

</BLOCKQUOTE>

<P>

You can iterate through the hash table using indexes and pointers

to hash table entries using the <TT><FONT FACE="Courier">HE</FONT></TT>

pointer type. To iterate through the array (such as with the <TT><FONT FACE="Courier">each</FONT></TT>

command in Perl), you can use <TT><FONT FACE="Courier">hv_iterinit(HV*)</FONT></TT>

to set the starting point and then get the next item as an <TT><FONT FACE="Courier">HE</FONT></TT>

pointer from a call to the <TT><FONT FACE="Courier">hv_iternext(HV*)</FONT></TT>

function. To get the item being traversed, make a call to this

function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">SV*&nbsp;&nbsp;&nbsp;&nbsp;hv_iterval(HV*

hashptr, HE* entry);</FONT></TT>

</BLOCKQUOTE>

<P>

The next <TT><FONT FACE="Courier">SV</FONT></TT> is available

via a call to this function:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">SV*&nbsp;&nbsp;&nbsp;&nbsp;hv_iternextsv(HV*hptr,

char** key, I32* retlen);</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">key</FONT></TT> and <TT><FONT FACE="Courier">retlen</FONT></TT>

arguments are return values for the key and its length. See line

600 in the <TT><FONT FACE="Courier">hv.c</FONT></TT>.

<H2><A NAME="MortalityofVariables"><B><FONT SIZE=5 COLOR=#FF0000>Mortality

of Variables</FONT></B></A></H2>

<P>

Values in Perl exist until explicitly freed. They are freed by

the Perl garbage collector when the reference count to them is

zero, by a call to the <TT><FONT FACE="Courier">undef</FONT></TT>

function, or if they were declared <TT><FONT FACE="Courier">local</FONT></TT>

or <TT><FONT FACE="Courier">my</FONT></TT> and the scope no longer

exists. In all other cases, variables declared in one scope persist

even after execution has left the code block in which they were

declared. For example, declaring and using <TT><FONT FACE="Courier">$a</FONT></TT>

in a function keeps <TT><FONT FACE="Courier">$a</FONT></TT> in

the main program even after returning from the subroutine. This

is why it's necessary to create local variables in subroutines

using the <TT><FONT FACE="Courier">my</FONT></TT> keyword so that

the Perl interpreter will automatically destroy these variables,

which will no longer be used after the subroutine returns.

<P>

References to variables in Perl can also be modified using the

following functions:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">int SvREFCNT(SV* sv);<BR>

</FONT></TT>This function returns the current reference count

to an existing <TT><FONT FACE="Courier">SV</FONT></TT>.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void SvREFCNT_inc(SV* sv);<BR>

</FONT></TT>This function increments the current reference count.

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">void SvREFCNT_dec(SV* sv);<BR>

</FONT></TT>This function decrements the current reference count.

You can make the reference count be zero to delete the <TT><FONT FACE="Courier">SV</FONT></TT>

being pointed to and let the garbage handler get rid <BR>

of it.

</BLOCKQUOTE>

<P>

Because the values declared within code blocks persist for a long

time, they are referred to as <I>immortal</I>. Sometimes declaring

and creating variable names in code blocks have the side effect

of persisting even if you do not want them to. When writing code

that declares and creates such variables, it's a good idea to

create variables that you do not want to persist as <I>mortal</I>;

that is, they die when code leaves the current scope.

<P>

The functions that create a mortal variable are as follows:<P>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR VALIGN=TOP><TD WIDTH=243><TT><FONT FACE="Courier">SV* sv_newmortal();</FONT></TT>

</TD><TD WIDTH=347>This function creates a new mortal variable and returns a pointer to it.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=243><TT><FONT FACE="Courier">SV* sv_2mortal(SV*);</FONT></TT>

</TD><TD WIDTH=347>This function converts an existing immortal <TT><FONT FACE="Courier">SV</FONT></TT> into a mortal variable. Be careful not to convert an already mortal <TT><FONT FACE="Courier">SV</FONT></TT> into a mortal <TT><FONT 

FACE="Courier">SV</FONT></TT> because this operation may result in the reference count for the variable to be decremented twice, leading to unpredictable results.

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=243><TT><FONT FACE="Courier">SV* sv_mortalcopy(SV*);</FONT></TT>

</TD><TD WIDTH=347>This function copies an existing <TT><FONT FACE="Courier">SV</FONT></TT> (without regard to the mortality of the passed <TT><FONT FACE="Courier">SV</FONT></TT>) into a new mortal <TT><FONT FACE="Courier">SV</FONT></TT>.

</TD></TR>

</TABLE></CENTER>

<P>

<P>

To create <TT><FONT FACE="Courier">AV</FONT></TT> and <TT><FONT FACE="Courier">HV</FONT></TT>

types, you have to cast the input parameters to and from these

three functions as <TT><FONT FACE="Courier">AV*</FONT></TT> and

<TT><FONT FACE="Courier">HV*</FONT></TT>.

<H2><A NAME="SubroutinesandStacks"><B><FONT SIZE=5 COLOR=#FF0000>Subroutines

and Stacks</FONT></B></A></H2>

<P>

Perl subroutines use the stack to get and return values to the

callers. <A HREF="ch27.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch27.htm" >Chapter 27</A>, &quot;Writing  Extensions

in C,&quot; covers how the stack is manipulated. This section

describes the functions available for you to manipulate the stack.

<P>

<CENTER>

<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>

<TR VALIGN=TOP><TD ><B>Note</B></TD></TR>

<TR VALIGN=TOP><TD >

<BLOCKQUOTE>

Look in the <TT><FONT FACE="Courier">XSUB.h</FONT></TT> file for more details than this chapter can give you. The details in the header include macro definitions for manipulating the stack in an extension module.

</BLOCKQUOTE>



</TD></TR>

</TABLE></CENTER>

<P>

<P>

Arguments on a stack to a Perl function are available via the

<TT><FONT FACE="Courier">ST(n)</FONT></TT> macro set. The topmost

item on the stack is <TT><FONT FACE="Courier">ST(0)</FONT></TT>,

and the <I>m</I>th one is <TT><FONT FACE="Courier">ST(m-1)</FONT></TT>.

You may assign the return value to a static value, like this:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">SV *arg1 = ST(1); // Assign argument[1]

to arg1;</FONT></TT>

</BLOCKQUOTE>

<P>

You can even increase the size of the argument stack in a function.

(This is necessary if you are returning a list from a function

call, for example. I cover this in more detail in <A HREF="ch27.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch27.htm" >Chapter 27</A>.)

To increase the length of the stack, make a call to the macro:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">EXTEND(<I>sp, num</I>);</FONT></TT>

</BLOCKQUOTE>

<P>

<TT><FONT FACE="Courier">sp</FONT></TT> is the stack pointer and

<TT><FONT FACE="Courier">num</FONT></TT> is an extra number of

elements to add to the stack. You cannot decrease the size of

the stack.

<P>

To add items to the stack, you have to specify the type of variable

you're adding. Four functions are available for four of the most

generic types to push:

<UL>

<LI><TT><FONT FACE="Courier">PUSHi(<I>IV</I>)</FONT></TT>

<LI><TT><FONT FACE="Courier">PUSHn(<I>double</I>)</FONT></TT>

<LI><TT><FONT FACE="Courier">PUSHp(<I>char*, I32</I>)</FONT></TT>

<LI><TT><FONT FACE="Courier">PUSHs(<I>SV*</I>)</FONT></TT>

</UL>

<P>

If you want the stack to be adjusted automatically, make the calls

to these macros:

<UL>

<LI><TT><FONT FACE="Courier">XPUSHi(IV)</FONT></TT>

<LI><TT><FONT FACE="Courier">XPUSHn(double)</FONT></TT>

<LI><TT><FONT FACE="Courier">XPUSHp(char*, I32)</FONT></TT>

<LI><TT><FONT FACE="Courier">XPUSHs(SV*)</FONT></TT>

</UL>

<P>

These macros are a bit slower but simpler to use.

<P>

In <A HREF="ch27.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch27.htm" >Chapter 27</A>, you'll see how to use stacks

in the section titled &quot;The <TT><FONT FACE="Courier">typemap</FONT></TT>

File.&quot; Basically, a <TT><FONT FACE="Courier">typemap</FONT></TT>

file is used by the extensions compiler <TT><FONT FACE="Courier">xsubpp</FONT></TT>

for the rules to convert from Perl's internal data types (<TT><FONT FACE="Courier">hash</FONT></TT>,

<TT><FONT FACE="Courier">array</FONT></TT>, and so on) to C's

data types (<TT><FONT FACE="Courier">int</FONT></TT>, <TT><FONT FACE="Courier">char

*</FONT></TT>, and so on). These rules are stored in the <TT><FONT FACE="Courier">typemap</FONT></TT>

file in your Perl distribution's <TT><FONT FACE="Courier">./lib/ExtUtils</FONT></TT>

directory.

<P>

The definitions of the structures in the <TT><FONT FACE="Courier">typemap</FONT></TT>

file are specified in the internal format for Perl.

<H2><A NAME="WhatIsMagic"><B><FONT SIZE=5 COLOR=#FF0000>What Is

Magic?</FONT></B></A></H2>

<P>

As you go through the online docs and the source for Perl, you'll

often see the word <I>magic</I>. The mysterious connotations of

this word are further enhanced by the almost complete lack of

documentation on what magic really is. In order to understand

the phrases &quot;then magic is applied to whatever&quot; or &quot;automagically

[sic]&quot; in the Perl documentation, you have to know what &quot;magic&quot;

in Perl really means. Perhaps after reading this section, you

will have a better feel for Perl internal structures and actions

of the Perl interpreter.

<P>

Basically, a scalar value in Perl can have special features for

it to become &quot;magical.&quot; When you apply magic to a variable,

that variable is placed into a linked list for methods. A method

is called for each type of magic assigned to that variable when

a certain action takes place, such as retrieving or storing the

contents of the variable. Please refer to a comparable scheme

in Perl when using the <TT><FONT FACE="Courier">tie()</FONT></TT>

function as described in <A HREF="ch6.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch6.htm" >Chapter 6</A>, &quot;Binding

Variables to Objects.&quot; When <I>tie</I>-ing a variable to

an action, you are defining actions to take when a scalar is accessed

or when an array item is read from. In the case of magic actions

of a scalar, you have a set of magic methods that are called when

the Perl interpreter takes a similar action on (like getting a

value from or putting a value into) a scalar variable.

<P>

To check whether a variable has magic methods associated with

it, you can get the flags for it using the <TT><FONT FACE="Courier">SvFLAGS(sv)</FONT></TT>

macro. The <TT><FONT FACE="Courier">(sv)</FONT></TT> here is the

⌨️ 快捷键说明

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