simple.html

来自「perl教程」· HTML 代码 · 共 601 行 · 第 1/3 页

HTML
601
字号
<?xml version="1.0" ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!-- saved from url=(0017)http://localhost/ -->
<script language="JavaScript" src="../../displayToc.js"></script>
<script language="JavaScript" src="../../tocParas.js"></script>
<script language="JavaScript" src="../../tocTab.js"></script>
<link rel="stylesheet" type="text/css" href="../../scineplex.css">
<title>Filter::Simple - Simplified source filtering</title>
<link rel="stylesheet" href="../../Active.css" type="text/css" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:" />
</head>

<body>

<script>writelinks('__top__',2);</script>
<h1><a>Filter::Simple - Simplified source filtering</a></h1>
<p><a name="__index__"></a></p>

<!-- INDEX BEGIN -->

<ul>

	<li><a href="#name">NAME</a></li>
	<li><a href="#synopsis">SYNOPSIS</a></li>
	<li><a href="#description">DESCRIPTION</a></li>
	<ul>

		<li><a href="#the_problem">The Problem</a></li>
		<li><a href="#a_solution">A Solution</a></li>
		<li><a href="#disabling_or_changing__no__behaviour">Disabling or changing &lt;no&gt; behaviour</a></li>
		<li><a href="#allinone_interface">All-in-one interface</a></li>
		<li><a href="#filtering_only_specific_components_of_source_code">Filtering only specific components of source code</a></li>
		<li><a href="#filtering_only_the_code_parts_of_source_code">Filtering only the code parts of source code</a></li>
		<li><a href="#using_filter__simple_with_an_explicit_import_subroutine">Using Filter::Simple with an explicit <a href="../../lib/Pod/perlfunc.html#item_import"><code>import</code></a> subroutine</a></li>
		<li><a href="#using_filter__simple_and_exporter_together">Using Filter::Simple and Exporter together</a></li>
		<li><a href="#how_it_works">How it works</a></li>
	</ul>

	<li><a href="#author">AUTHOR</a></li>
	<li><a href="#copyright">COPYRIGHT</a></li>
</ul>
<!-- INDEX END -->

<hr />
<p>
</p>
<h1><a name="name">NAME</a></h1>
<p>Filter::Simple - Simplified source filtering</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
 <span class="comment"># in MyFilter.pm:</span>
</pre>
<pre>
     <span class="keyword">package</span> <span class="variable">MyFilter</span><span class="operator">;</span>
</pre>
<pre>
     <span class="keyword">use</span> <span class="variable">Filter::Simple</span><span class="operator">;</span>
     
     <span class="variable">FILTER</span> <span class="operator">{</span> <span class="operator">...</span> <span class="operator">};</span>
</pre>
<pre>
     <span class="comment"># or just:</span>
     <span class="comment">#</span>
     <span class="comment"># use Filter::Simple sub { ... };</span>
</pre>
<pre>
 <span class="comment"># in user's code:</span>
</pre>
<pre>
     <span class="keyword">use</span> <span class="variable">MyFilter</span><span class="operator">;</span>
</pre>
<pre>
     <span class="comment"># this code is filtered</span>
</pre>
<pre>
     <span class="keyword">no</span> <span class="variable">MyFilter</span><span class="operator">;</span>
</pre>
<pre>
     <span class="comment"># this code is not</span>
</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>
</p>
<h2><a name="the_problem">The Problem</a></h2>
<p>Source filtering is an immensely powerful feature of recent versions of Perl.
It allows one to extend the language itself (e.g. the Switch module), to 
simplify the language (e.g. Language::Pythonesque), or to completely recast the
language (e.g. Lingua::Romana::Perligata). Effectively, it allows one to use
the full power of Perl as its own, recursively applied, macro language.</p>
<p>The excellent Filter::Util::Call module (by Paul Marquess) provides a
usable Perl interface to source filtering, but it is often too powerful
and not nearly as simple as it could be.</p>
<p>To use the module it is necessary to do the following:</p>
<ol>
<li>
<p>Download, build, and install the Filter::Util::Call module.
(If you have Perl 5.7.1 or later, this is already done for you.)</p>
</li>
<li>
<p>Set up a module that does a <code>use Filter::Util::Call</code>.</p>
</li>
<li>
<p>Within that module, create an <a href="../../lib/Pod/perlfunc.html#item_import"><code>import</code></a> subroutine.</p>
</li>
<li>
<p>Within the <a href="../../lib/Pod/perlfunc.html#item_import"><code>import</code></a> subroutine do a call to <code>filter_add</code>, passing
it either a subroutine reference.</p>
</li>
<li>
<p>Within the subroutine reference, call <code>filter_read</code> or <code>filter_read_exact</code>
to &quot;prime&quot; $_ with source code data from the source file that will
<a href="../../lib/Pod/perlfunc.html#item_use"><code>use</code></a> your module. Check the status value returned to see if any
source code was actually read in.</p>
</li>
<li>
<p>Process the contents of $_ to change the source code in the desired manner.</p>
</li>
<li>
<p>Return the status value.</p>
</li>
<li>
<p>If the act of unimporting your module (via a <a href="../../lib/Pod/perlfunc.html#item_no"><code>no</code></a>) should cause source
code filtering to cease, create an <code>unimport</code> subroutine, and have it call
<code>filter_del</code>. Make sure that the call to <code>filter_read</code> or
<code>filter_read_exact</code> in step 5 will not accidentally read past the
<a href="../../lib/Pod/perlfunc.html#item_no"><code>no</code></a>. Effectively this limits source code filters to line-by-line
operation, unless the <a href="../../lib/Pod/perlfunc.html#item_import"><code>import</code></a> subroutine does some fancy
pre-pre-parsing of the source code it's filtering.</p>
</li>
</ol>
<p>For example, here is a minimal source code filter in a module named
BANG.pm. It simply converts every occurrence of the sequence <code>BANG\s+BANG</code>
to the sequence <code>die 'BANG' if $BANG</code> in any piece of code following a
<code>use BANG;</code> statement (until the next <code>no BANG;</code> statement, if any):</p>
<pre>
    <span class="keyword">package</span> <span class="variable">BANG</span><span class="operator">;</span>
     
    <span class="keyword">use</span> <span class="variable">Filter::Util::Call</span> <span class="operator">;</span>
</pre>
<pre>
    <span class="keyword">sub</span><span class="variable"> import </span><span class="operator">{</span>
        <span class="variable">filter_add</span><span class="operator">(</span> <span class="keyword">sub</span><span class="variable"> </span><span class="operator">{</span>
        <span class="keyword">my</span> <span class="variable">$caller</span> <span class="operator">=</span> <span class="keyword">caller</span><span class="operator">;</span>
        <span class="keyword">my</span> <span class="operator">(</span><span class="variable">$status</span><span class="operator">,</span> <span class="variable">$no_seen</span><span class="operator">,</span> <span class="variable">$data</span><span class="operator">);</span>
        <span class="keyword">while</span> <span class="operator">(</span><span class="variable">$status</span> <span class="operator">=</span> <span class="variable">filter_read</span><span class="operator">())</span> <span class="operator">{</span>
            <span class="keyword">if</span> <span class="operator">(</span><span class="regex">/^\s*no\s+$caller\s*;\s*?$/</span><span class="operator">)</span> <span class="operator">{</span>
                <span class="variable">$no_seen</span><span class="operator">=</span><span class="number">1</span><span class="operator">;</span>
                <span class="keyword">last</span><span class="operator">;</span>
            <span class="operator">}</span>
            <span class="variable">$data</span> <span class="operator">.=</span> <span class="variable">$_</span><span class="operator">;</span>
            <span class="variable">$_</span> <span class="operator">=</span> <span class="string">""</span><span class="operator">;</span>
        <span class="operator">}</span>
        <span class="variable">$_</span> <span class="operator">=</span> <span class="variable">$data</span><span class="operator">;</span>
        <span class="regex">s/BANG\s+BANG/die 'BANG' if \$BANG/g</span>
            <span class="keyword">unless</span> <span class="variable">$status</span> <span class="operator">&lt;</span> <span class="number">0</span><span class="operator">;</span>
        <span class="variable">$_</span> <span class="operator">.=</span> <span class="string">"no $class;\n"</span> <span class="keyword">if</span> <span class="variable">$no_seen</span><span class="operator">;</span>
        <span class="keyword">return</span> <span class="number">1</span><span class="operator">;</span>
        <span class="operator">})</span>
    <span class="operator">}</span>
</pre>
<pre>
    <span class="keyword">sub</span><span class="variable"> unimport </span><span class="operator">{</span>
        <span class="variable">filter_del</span><span class="operator">();</span>
    <span class="operator">}</span>
</pre>
<pre>
    <span class="number">1</span> <span class="operator">;</span>
</pre>
<p>This level of sophistication puts filtering out of the reach of
many programmers.</p>
<p>
</p>
<h2><a name="a_solution">A Solution</a></h2>
<p>The Filter::Simple module provides a simplified interface to
Filter::Util::Call; one that is sufficient for most common cases.</p>
<p>Instead of the above process, with Filter::Simple the task of setting up
a source code filter is reduced to:</p>
<ol>
<li>
<p>Download and install the Filter::Simple module.
(If you have Perl 5.7.1 or later, this is already done for you.)</p>
</li>
<li>
<p>Set up a module that does a <code>use Filter::Simple</code> and then
calls <code>FILTER { ... }</code>.</p>
</li>
<li>
<p>Within the anonymous subroutine or block that is passed to
<code>FILTER</code>, process the contents of $_ to change the source code in
the desired manner.</p>
</li>
</ol>

⌨️ 快捷键说明

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