📄 ch25.htm
字号:
<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* 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* perl_get_hv("myHash",
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* perl_get_hv("myHash",
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 </FONT></TT>The
key of the hash item
<LI><TT><FONT FACE="Courier">U32 klen, </FONT></TT>The
length of the key
<LI><TT><FONT FACE="Courier">SV* val, </FONT></TT>The
scalar to insert
<LI><TT><FONT FACE="Courier">U32 hash) </FONT></TT>Zero
unless you compute the hash function yourself
<LI><TT><FONT FACE="Courier">SV** 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 </FONT></TT>The
length of the key
<LI><TT><FONT FACE="Courier">I32 lval) </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* 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* 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>, "Writing Extensions
in C," 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 "The <TT><FONT FACE="Courier">typemap</FONT></TT>
File." 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 "then magic is applied to whatever" or "automagically
[sic]" in the Perl documentation, you have to know what "magic"
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 "magical." 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>, "Binding
Variables to Objects." 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 + -