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

📄 ch25.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 4 页
字号:
name of the variable. The <TT><FONT FACE="Courier">SvMAGIC(variable)</FONT></TT>

macro returns the list of methods that are magically applied to

the variable. The <TT><FONT FACE="Courier">SvTYPE()</FONT></TT>

of the variable is <TT><FONT FACE="Courier">SVt_PVMG</FONT></TT>

if it has a list of methods. A normal <TT><FONT FACE="Courier">SV</FONT></TT>

type is upgraded to a magical status by Perl if a method is requested

for it.

<P>

The structure to maintain the list is found in the file <TT><FONT FACE="Courier">mg.h</FONT></TT>

in the Perl source files:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">struct magic {<BR>

&nbsp;&nbsp;&nbsp;&nbsp;MAGIC*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mg_moremagic;

<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

pointer to next method. NULL if none.<BR>

&nbsp;&nbsp;&nbsp;&nbsp;MGVTBL*&nbsp;&nbsp;&nbsp;&nbsp;mg_virtual;

<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;pointer

to table of methods.<BR>

&nbsp;&nbsp;&nbsp;&nbsp;U16&nbsp;&nbsp;&nbsp;mg_private;&nbsp;&nbsp;&nbsp;//

internal variable<BR>

&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;mg_type;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

type of methods<BR>

&nbsp;&nbsp;&nbsp;&nbsp;U8&nbsp;&nbsp;&nbsp;&nbsp;mg_flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

flags for this method<BR>

&nbsp;&nbsp;&nbsp;&nbsp;SV*&nbsp;&nbsp;&nbsp;mg_obj;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

Reference to itself<BR>

&nbsp;&nbsp;&nbsp;&nbsp;char*&nbsp;mg_ptr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

name of the magic variable<BR>

&nbsp;&nbsp;&nbsp;&nbsp;I32&nbsp;&nbsp;&nbsp;mg_len;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//

length of the name<BR>

};</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">mg_type</FONT></TT> value sets up

how the magic function is applied. The following items are used

in the magic table. You can see the values in use in the <TT><FONT FACE="Courier">sv.c</FONT></TT>

file at about line 1950. Table 25.2, which has been constructed

from the <TT><FONT FACE="Courier">switch</FONT></TT> statement,

tells you how methods have to be applied.<BR>

<P>

<CENTER><B>Table 25.2. Types of Magic functions in </B><TT><B><FONT FACE="Courier">mg_type</FONT></B></TT><B>.</B></CENTER>

<P>

<CENTER>

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

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><I><FONT FACE="Courier">Mg_type</FONT></I></TT></CENTER>

</TD><TD WIDTH=166><I>Virtual Magic Table</I></TD><TD WIDTH=209><I>Action Calling Method</I>

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">\0</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_sv</FONT></TT>

</TD><TD WIDTH=209>Null operation</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">A</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_amagic</FONT></TT>

</TD><TD WIDTH=209>Operator overloading</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">a</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_amagicelem</FONT></TT>

</TD><TD WIDTH=209>Operator overloading</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">c</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">0</FONT></TT></TD>

<TD WIDTH=209>Used in operator overloading</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">B</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_bm</FONT></TT>

</TD><TD WIDTH=209>Unknown</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">E</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_env</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">%ENV</FONT></TT> hash

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">e</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_envelem</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">%ENV</FONT></TT> hash element

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">g</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_mglob</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">Regexp</FONT></TT> applied globally

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">I</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_isa</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">@ISA</FONT></TT> array

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">i</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_isaelem</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">@ISA</FONT></TT> array element

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">L</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">0</FONT></TT></TD>

<TD WIDTH=209>Unknown</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">l</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">tbl_dbline</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">n</FONT></TT> line debugger

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">P</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">tbl_pack</FONT></TT>

</TD><TD WIDTH=209>Tied array or hash</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">p</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_packelem</FONT></TT>

</TD><TD WIDTH=209>Tied array or hash element</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">q</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_packelem</FONT></TT>

</TD><TD WIDTH=209>Tied scalar or handle</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">S</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_sig</FONT></TT>

</TD><TD WIDTH=209>Signal hash</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">s</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_sigelem</FONT></TT>

</TD><TD WIDTH=209>Signal hash element</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">t</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_taint</FONT></TT>

</TD><TD WIDTH=209>Modified tainted variable</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">U</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_uvar</FONT></TT>

</TD><TD WIDTH=209>Unknown variable type</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">v</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_vec</FONT></TT>

</TD><TD WIDTH=209>Vector</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">x</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_substr</FONT></TT>

</TD><TD WIDTH=209>Substring</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">*</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_glob</FONT></TT>

</TD><TD WIDTH=209>The <TT><FONT FACE="Courier">GV</FONT></TT> type

</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">#</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_arylen</FONT></TT>

</TD><TD WIDTH=209>Array length</TD></TR>

<TR VALIGN=TOP><TD WIDTH=90><CENTER><TT><FONT FACE="Courier">&nbsp;.</FONT></TT></CENTER>

</TD><TD WIDTH=166><TT><FONT FACE="Courier">vtbl_pos</FONT></TT>

</TD><TD WIDTH=209><TT><FONT FACE="Courier">$.</FONT></TT> scalar variable

</TD></TR>

</TABLE></CENTER>

<P>

<P>

The magic virtual tables are defined in <TT><FONT FACE="Courier">embed.h</FONT></TT>.

The <TT><FONT FACE="Courier">mg_virtual</FONT></TT> field in each

magic entry is assigned to the address of the virtual table.

<P>

Each entry in the magic virtual table has five items, each of

which is defined in the following structure in the file <TT><FONT FACE="Courier">mg.h</FONT></TT>:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">struct mgvtbl {<BR>

&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*svt_get)&nbsp;&nbsp;&nbsp;&nbsp;_((SV

*sv, MAGIC* mg));<BR>

&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*svt_set)&nbsp;&nbsp;&nbsp;&nbsp;_((SV

*sv, MAGIC* mg));<BR>

&nbsp;&nbsp;&nbsp;&nbsp;U32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*svt_len)&nbsp;&nbsp;&nbsp;&nbsp;_((SV

*sv, MAGIC* mg));<BR>

&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*svt_clear)&nbsp;&nbsp;_((SV

*sv, MAGIC* mg));<BR>

&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*svt_free)&nbsp;&nbsp;&nbsp;_((SV

*sv, MAGIC* mg));<BR>

};</FONT></TT>

</BLOCKQUOTE>

<P>

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

called when the data in <TT><FONT FACE="Courier">SV</FONT></TT>

is retrieved. The <TT><FONT FACE="Courier">svt_set()</FONT></TT>

function is called when the data in <TT><FONT FACE="Courier">SV</FONT></TT>

is stored. The <TT><FONT FACE="Courier">svt_len()</FONT></TT>

function is called when the length of the string is changed. The

<TT><FONT FACE="Courier">svt_clear()</FONT></TT> function is called

when <TT><FONT FACE="Courier">SV</FONT></TT> is cleared, and the

<TT><FONT FACE="Courier">svt_free()</FONT></TT> function is called

when <TT><FONT FACE="Courier">SV</FONT></TT> is destroyed.

<P>

All tables shown in the <TT><FONT FACE="Courier">perl.h</FONT></TT>

file are assigned <TT><FONT FACE="Courier">mgvtbl</FONT></TT>

structures. The values in each <TT><FONT FACE="Courier">mgvtbl</FONT></TT>

structure for each item in a table define a function to call when

an action that affects entries in this table is taken by the Perl

interpreter. Here is an excerpt from the file:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">EXT MGVTBL vtbl_sv =<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{magic_get, magic_set, magic_len,0,0};

<BR>

EXT MGVTBL vtbl_env =<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;0};

<BR>

EXT MGVTBL vtbl_envelem =<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,&nbsp;&nbsp;magic_setenv, 0,magic_clearenv,

0};<BR>

EXT MGVTBL vtbl_sig =<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,&nbsp;&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;0,&nbsp;&nbsp;0,&nbsp;&nbsp;0};

<BR>

EXT MGVTBL vtbl_sigelem =<BR>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{0,&nbsp;&nbsp;magic_setsig, 0,0,

0};</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">vbtl_sv</FONT></TT> is set to call

three methods: <TT><FONT FACE="Courier">magic_get()</FONT></TT>,

<TT><FONT FACE="Courier">magic_set()</FONT></TT>, and <TT><FONT FACE="Courier">magic_len()</FONT></TT>

for the magic entries in <TT><FONT FACE="Courier">sv</FONT></TT>.

The zeros for <TT><FONT FACE="Courier">vtbl_sig</FONT></TT> indicate

that no magic methods are called.

<H2><A NAME="TheGlobalVariableGVType"><B><FONT SIZE=5 COLOR=#FF0000>The

Global Variable </FONT></B><TT><B><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">(GV)</FONT></B></TT><B><FONT SIZE=5 COLOR=#FF0000>

Type</FONT></B></A></H2>

<P>

If you are still awake, you'll notice a reference to <TT><FONT FACE="Courier">GV</FONT></TT>

in the source file. <TT><FONT FACE="Courier">GV</FONT></TT> stands

for <I>global variable</I>,<I> </I>and the value stored in <TT><FONT FACE="Courier">GV</FONT></TT>

is any data type from scalar to a subroutine reference. <TT><FONT FACE="Courier">GV</FONT></TT>

entries are stored in a hash table, and the keys to each entry

are the names of the symbols being stored. A hash table with <TT><FONT FACE="Courier">GV</FONT></TT>

entries is also referred to as a stash. Internally, a <TT><FONT FACE="Courier">GV</FONT></TT>

type is the same as an <TT><FONT FACE="Courier">HV</FONT></TT>

type.

<P>

Keys in a stash are also package names, with the data item pointing

to other <TT><FONT FACE="Courier">GV</FONT></TT> tables containing

the symbol within the package.

<H2><A NAME="WheretoLookforMoreInformation"><B><FONT SIZE=5 COLOR=#FF0000>Where

to Look for More Information</FONT></B></A></H2>

<P>

Most of the information in this chapter has been gleaned from

source files or the online documents on the Internet. There is

a somewhat old file called <TT><FONT FACE="Courier">perlguts.html</FONT></TT>

by Jeff Okamoto (e-mail <TT><FONT FACE="Courier">okamoto@corp.hp.com</FONT></TT>)

in the <TT><FONT FACE="Courier">www.metronet.com</FONT></TT> archives

that has the Perl API functions and information about the internals.

<P>

Note that the <TT><FONT FACE="Courier">perlguts.html</FONT></TT>

file was dated 1/27/1995, so it's probably not as up-to-date as

you would like.

<P>

Please refer to the <TT><FONT FACE="Courier">perlguts.html</FONT></TT>

or the <TT><FONT FACE="Courier">perlguts</FONT></TT> man page

for a comprehensive listing of the Perl API. If you want a listing

of the functions in the Perl source code and the search strings,

use the <TT><FONT FACE="Courier">ctags *.c</FONT></TT> command

on all the <TT><FONT FACE="Courier">.c</FONT></TT> files in the

Perl source directory. The result will be a very long file (800

lines), called <TT><FONT FACE="Courier">tags</FONT></TT>, in the

same directory. A header of this file is shown here:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">ELSIF&nbsp;&nbsp;&nbsp;&nbsp; perly.c&nbsp;&nbsp;&nbsp;/^&quot;else

: ELSIF '(' expr ')' block else&quot;,$/<BR>

GvAVn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gv.c&nbsp;/^AV *GvAVn(gv)$/

<BR>

GvHVn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gv.c&nbsp;/^HV *GvHVn(gv)$/

<BR>

Gv_AMupdate&nbsp;&nbsp;&nbsp;&nbsp;gv.c /^Gv_AMupdate(stash)$/

<BR>

HTOV util.c&nbsp;&nbsp;&nbsp;&nbsp;/^HTOV(htovs,short)$/<BR>

PP&nbsp;&nbsp;&nbsp;pp.c /^PP(pp_abs)$/<BR>

PP&nbsp;&nbsp;&nbsp;pp.c /^PP(pp_anoncode)$/<BR>

PP&nbsp;&nbsp;&nbsp;pp.c /^PP(pp_anonhash)$/<BR>

PP&nbsp;&nbsp;&nbsp;pp.c /^PP(pp_anonlist)$/<BR>

PP&nbsp;&nbsp;&nbsp;pp.c /^PP(pp_aslice)$/</FONT></TT>

</BLOCKQUOTE>

<P>

If you are a <TT><FONT FACE="Courier">vi</FONT></TT> hack, you

can type <TT><I><FONT FACE="Courier">:tag functionName</FONT></I></TT>

to go to the line and file immediately from within a <TT><FONT FACE="Courier">vi</FONT></TT>

session. Ah, the old <TT><FONT FACE="Courier">vi</FONT></TT> editor

still has a useful function in this day and age. <TT><FONT FACE="Courier">emacs</FONT></TT>

users can issue the command <TT><FONT FACE="Courier">etags *.c</FONT></TT>

and get a comparable <TT><FONT FACE="Courier">tags</FONT></TT>

file for use with the <TT><FONT FACE="Courier">M-x find-tag</FONT></TT>

command in <TT><FONT FACE="Courier">emacs</FONT></TT>.

<H2><A NAME="Summary"><B><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></B></A>

</H2>

<P>

This chapter is a reference-only chapter to prepare you for what

lies ahead in the rest of the book. You'll probably be referring

to this chapter quite a bit as you write <TT><FONT FACE="Courier">include</FONT></TT>

extensions.

<P>

There are three basic types of variables in Perl: <TT><FONT FACE="Courier">SV</FONT></TT>

for scalar, <TT><FONT FACE="Courier">AV</FONT></TT> for arrays,

and <TT><FONT FACE="Courier">HV</FONT></TT> for hash values. Macros

exist for getting data from one type to another. You'll need to

know about these internal data types if you're going to be writing

Perl extensions, dealing with platform-dependent issues, or (ugh)

embedding C code in Perl and vice versa. The dry information in

this chapter will serve you well in the rest of this book.

<P>

<HR WIDTH="100%"></P>



<CENTER><P><A HREF="ch24.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch24.htm"><IMG SRC="pc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/index.htm"><IMG SRC="hb.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch26.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch26.htm"><IMG 

SRC="nc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A></P></CENTER>



<P>

<HR WIDTH="100%"></P>



</BODY>

</HTML>

⌨️ 快捷键说明

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