зеркало из https://github.com/mozilla/pjs.git
Bug 191778 Fix minor errors in perlconnect readme
r=brendan
This commit is contained in:
Родитель
a7e2362c04
Коммит
1c09f596eb
|
@ -1,345 +0,0 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
|
||||
<meta name="Author" content="Vladimir Livshits">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]">
|
||||
<title>PerlConnect Documentation</title>
|
||||
<style>
|
||||
A:link {text-decoration: none}
|
||||
A:visited {text-decoration: none}
|
||||
</style>
|
||||
</head>
|
||||
<body background="bg.jpg">
|
||||
|
||||
<center>
|
||||
<h3>
|
||||
P<font size=-1>ERL</font>C<font size=-1>ONNECT AND </font>JS<font size=+0>.PM</font></h3></center>
|
||||
|
||||
<center>U<font size=-1>SER-LEVEL </font><font size=+1>D</font><font size=-1>OCUMENTATION</font>
|
||||
<br><a href="mailto:val4@cornell.edu">Vladimir Livshits</a>
|
||||
<br>
|
||||
<hr SIZE=1 NOSHADE WIDTH="100%"></center>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#History">Update history</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Overview">Overview</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Features">Features</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Design">Design</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Installation">Installation</a></li>
|
||||
|
||||
<li>
|
||||
<a href="#Limitations">Current Limitations and Futher Work</a></li>
|
||||
</ol>
|
||||
|
||||
<h4>
|
||||
<a NAME="History"></a>Update History</h4>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
3/8/99 -- added some more details, especially pertaining to <tt>PerlConnect.pm</tt></li>
|
||||
|
||||
<li>
|
||||
8/98 -- this document created</li>
|
||||
</ul>
|
||||
|
||||
<h4>
|
||||
<a NAME="Overview"></a>Overview</h4>
|
||||
PerlConnect provides glue for the developer between JavaScript and Perl.
|
||||
It currently consists of two parts, PerlConnect implemented in C and JS.pm,
|
||||
a Perl module written using XSUBs. PerlConnect and JS.pm allow calling
|
||||
Perl from JS and JS from Perl, respectively. Whenever possible, it is attempted
|
||||
to archieve the maximum level of transparency for calling one language
|
||||
from the other. This is done by converting values between the two languages,
|
||||
creating wrappers around objects, and emulating the standard language syntax.
|
||||
<h4>
|
||||
<a NAME="Features"></a>PerlConnect Features</h4>
|
||||
PerlConnect allows running a Perl interpreter concurrently with your JavaScript
|
||||
embedding and executing Perl commands from JavaScript. You usually need
|
||||
to create a Perl interpreter by saysing something like this:
|
||||
<blockquote><tt>p = new Perl('Sys::Hostname', 'Test::Harness')</tt></blockquote>
|
||||
In addition to creating an interpreter, this will also include the libraries
|
||||
you pass to the Perl constructor, which is equivalent to <tt>use Sys::Hostname;
|
||||
use Test::Harness</tt>. You can always include libraries explicitly by
|
||||
using <tt>p.eval('use Sys::Hostname; use Test::Harness')</tt>. There is
|
||||
also another way to do this: <tt>p.use('Sys::Hostname', 'Test::Harness')</tt>.
|
||||
As you can see, TMTOWTDI.
|
||||
<p><b>Note: </b>If the statements above fail on you saying something about
|
||||
libraries not found in the search path, you need to make sure the modules
|
||||
PerlConnect uses, JS.pm and PerlConnect.pm live in some directory accessible
|
||||
from the search path. Seach path can be set by adjusting the value of PERLLIB
|
||||
and PERL5LIB environment variables. See <a href="#Installation">installation</a>
|
||||
for more details.
|
||||
<p><b>Note: </b>Despite the illusion p = new Perl(...) syntax might create,
|
||||
there is actually only one version of the Perl interpreter running. I.e.
|
||||
if you create two interpreters like this:
|
||||
<blockquote><tt>p = new Perl; q = new Perl;</tt>
|
||||
<br><tt>p.eval("$a='ha-'x20");</tt></blockquote>
|
||||
Now you'll see that <tt>q["$a"]</tt> will give you <tt>$a</tt>'s value
|
||||
from <tt>p</tt>.
|
||||
<p>Naturally, you will want to look at the result of your function calls
|
||||
and <tt>eval</tt> statements. Suppose, you do something like this:
|
||||
<blockquote><tt>line = p.eval("'-' x 80")</tt></blockquote>
|
||||
Perl's eval returns the last statement evaluated, unless you explicitly
|
||||
say <tt>return</tt>. So now <tt>line</tt> contains 80 dashes. You can do
|
||||
similar things with non-scalar data types:
|
||||
<blockquote><tt>p.use('Time::gmtime');</tt>
|
||||
<br><tt>t = p.eval('Time::gmtime::gmtime') // returns
|
||||
[49,0,4,24,6,98,5,204,0]</tt></blockquote>
|
||||
assigns a Perl array to <tt>t</tt>. You can print <tt>t</tt>, use the <tt>for/in</tt>
|
||||
syntax to walk through it, compute its lenght, etc. You can read and assign
|
||||
to individual elements using the standard syntax. However, PerlValues,
|
||||
that is, the value we get from Perl, don't support all the standard operations,
|
||||
for isntance, don't expect <tt>t.reverse()</tt> to work. Hashes can also
|
||||
be returned from Perl:
|
||||
<blockquote><tt>info=p.eval("{ver=>$], pid=>$$}")</tt></blockquote>
|
||||
Now you can look at individual hash keys like this:
|
||||
<blockquote><tt>info["ver"]</tt> or <tt>info.pid</tt></blockquote>
|
||||
Suppose you want to use Perl to perform pattern-based string replacement.
|
||||
Here's how you can do it from JavaScript:
|
||||
<blockquote><tt>p.eval("\</tt>
|
||||
<br><tt> sub perl_replace(){\</tt>
|
||||
<br><tt> my($string, $find, $replace)
|
||||
= @_;\</tt>
|
||||
<br><tt> eval(\"\\$string =~
|
||||
s/$find/$replace/g;\");\</tt>
|
||||
<br><tt> return $string;\</tt>
|
||||
<br><tt> }"</tt>
|
||||
<br><tt>);</tt></blockquote>
|
||||
and now
|
||||
<blockquote><tt>p.perl_replace('Quick brown fox jumped over a lazy dog',
|
||||
'dog', 'rhino')</tt></blockquote>
|
||||
produces what you'd expect.
|
||||
<p>You can use the same syntax to call procedures defined in modules other
|
||||
than<tt> main. </tt>The example with<tt> gmtime </tt>can be rewritten like
|
||||
this:
|
||||
<blockquote><tt>p.use('Time::gmtime');</tt>
|
||||
<br><tt>t = p.Time.gmtime.gmtime() // returns [49,0,4,24,6,98,5,204,0]</tt></blockquote>
|
||||
You can reference variables exported by modules others than <tt>main</tt>
|
||||
like this:
|
||||
<blockquote><tt>a=p.Foo.$bar </tt>or<tt> a=p.Foo["$bar"] </tt>or
|
||||
<br><tt>a=p.Foo["@bar"]</tt>or<tt> a=p.Foo["%bar"]</tt></blockquote>
|
||||
Each of the stetements above returns a either an immediate JS value, for
|
||||
scalar types, or a PerlValue for compound types. <tt>a.type </tt>contains
|
||||
the type of the PerlValue in <tt>a</tt>. <i>This may change because we
|
||||
may end up separating Perl hashes and arrays into separate classes.</i>
|
||||
<h4>
|
||||
JS.pm Features</h4>
|
||||
<i>JS.pm is much less tested then PerlConnect.</i> You should be able to
|
||||
do similar things from Perl. Just say
|
||||
<blockquote><tt>use JS;</tt>
|
||||
<br><tt>$js = <b>new</b> JS();</tt></blockquote>
|
||||
and now you can do something like this:
|
||||
<blockquote><tt>$js-><b>eval</b>(q/</tt>
|
||||
<blockquote><tt>Object o = {};</tt>
|
||||
<br><tt>o.a = 'p';</tt>
|
||||
<br><tt>o.b = 'q';</tt>
|
||||
<br><tt>return o;</tt></blockquote>
|
||||
<tt>/);</tt></blockquote>
|
||||
<b>Note:</b> Please see test.js and test.pl, test scripts that test and
|
||||
demonstrate various features of PerlConnect and JS.pm, respectively. They
|
||||
will help get you started.
|
||||
<h4>
|
||||
<a NAME="Design"></a>PerlConnect Design</h4>
|
||||
PerlConnect is written in C. It uses both JavaScript and Perl APIs and
|
||||
implements a mapping between the two. The following JavaScript objects
|
||||
are implemented by PerlConnect:
|
||||
<br>
|
||||
<center><table BORDER COLS=2 WIDTH="80%" >
|
||||
<tr ALIGN=CENTER BGCOLOR="#CCCCCC">
|
||||
<td ALIGN=CENTER VALIGN=CENTER WIDTH="20%"><b>Object</b></td>
|
||||
|
||||
<td><b>What it does</b></td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td WIDTH="30"><tt>Perl</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Perl Interpreter Object. It's prototype type
|
||||
is PerlModule, it corresponds to <tt>main::</tt>. Supports <tt>eval</tt>,
|
||||
<tt>call</tt>,
|
||||
<tt>use</tt>.</td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td><tt>PerlModule</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Implements JS-like syntax for Perl modules. Doesn't
|
||||
export provide any methods. <tt>path</tt> property shown the name of the
|
||||
Perl module the object represents.</td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td><tt>PerlValue</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Represents a value returned from <tt>eval</tt>,
|
||||
<tt>call</tt>,
|
||||
or obtained by using the subscript notation (<tt>p.Foo["@bar"]</tt>). Its
|
||||
Perl type is stored in the <tt>type</tt> property.</td>
|
||||
</tr>
|
||||
</table></center>
|
||||
|
||||
<p>See comments in the code, <tt>jsperl.c</tt> and <tt>JS.pm</tt> for more
|
||||
info.
|
||||
<br><b>Note: </b> PerlConnecte heavily relies on PerlConnect.pm, which
|
||||
does some background magic for it. PerlConnect.pm should <i>not</i> be
|
||||
used. Use JS.pm instead.
|
||||
<h4>
|
||||
JS.pm Design</h4>
|
||||
JSConnect is written using XSUBs, the language in which Perl extentions
|
||||
are implemented. See the output of <tt>man perlxs/perlguts/perlemberd/perlxsstut</tt>
|
||||
for more detais. The source files are <tt>JS.xs</tt> and <tt>typemap</tt>.
|
||||
After processing them using the XSUBs compiler, <tt>xsubpp</tt>, the resulting
|
||||
C file should be compiled into a DLL. See <tt>JS.xs</tt> for more details
|
||||
on how to to run the XSUBS compiler. You will need a sufficiently recent
|
||||
version of Perl to run JS.pm sucessfuly. <tt>JS.pm</tt> provides bootstraping
|
||||
mechanism to load this DLL.
|
||||
<p>The following Perl packages (objects) are implemented:
|
||||
<br>
|
||||
<center><table BORDER COLS=2 WIDTH="80%" >
|
||||
<tr ALIGN=CENTER BGCOLOR="#CCCCCC">
|
||||
<td ALIGN=CENTER VALIGN=CENTER WIDTH="20%"><b>Package</b></td>
|
||||
|
||||
<td><b>What it contains</b></td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td><tt>JS</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Doesn't not do anything in particular at this
|
||||
point except defining a constuctor. So one can say <tt>$js = <b>new</b>
|
||||
JS()</tt>, which will create a new runtime, add a context to it and return
|
||||
that Context. JS also defines a bunch of private functions called from
|
||||
C by PerlConnect. They are not exposed by default, but pushed onto <tt>@EXPORT_OK</tt>
|
||||
array instead.</td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td><tt>JS::Runtime</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Corresponds to <tt>JSRuntime*</tt> struct. Provides
|
||||
a constructor and destructor. The destructor is invoked automatically,
|
||||
so you don't have to worry about Runtime deallocation. Constructor syntax
|
||||
is the following: <tt>$rt = <b>new</b> JS::Runtime(10_000)</tt>, where
|
||||
the parameter is the same number you pass to <tt>JS_NewRuntime</tt>. There
|
||||
are many private functions created in <tt>JS.xs</tt> that are not exported
|
||||
by default.</td>
|
||||
</tr>
|
||||
|
||||
<tr ALIGN=CENTER VALIGN=CENTER>
|
||||
<td><tt>JS::Context</tt></td>
|
||||
|
||||
<td ALIGN=LEFT VALIGN=TOP>Corresponds to <tt>JSContext*</tt> struct. Provides
|
||||
a constructor and destructor. The destructor is invoked automatically,
|
||||
so you don't have to worry about Context deallocation. Constructor syntax
|
||||
is the following: <tt>$rt = <b>new</b> JS::Context($rt, 1_000)</tt>, where
|
||||
the parameter is the same number you pass to <tt>JS_NewContext</tt>. There
|
||||
are many private functions created in <tt>JS.xs</tt> that are not exported
|
||||
by default.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td ALIGN=CENTER><tt>JS::Object</tt></td>
|
||||
|
||||
<td>Corresponds to <tt>JSObject*</tt> struct. There is not that much here
|
||||
yet. This object is intended as a wrapper around the <tt>JSObject* stuct</tt>.
|
||||
Support for tying hashes and possibly arrays with <tt>JS::Objects</tt>
|
||||
is coming.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td ALIGN=CENTER><i><tt><font color="#000000">[JS::Array]</font></tt></i></td>
|
||||
|
||||
<td><i>I am not quite sure if this is needed. One might probably get away
|
||||
with just <tt>JS::Object</tt> defined. If it's implemented, it will be
|
||||
very much similar to <tt>JS::Object</tt> above.</i></td>
|
||||
</tr>
|
||||
</table></center>
|
||||
|
||||
<p>All the modules above follow the convention of storing the variable
|
||||
they return in the <tt>$this</tt> variable of the current class. So <tt>$JS::Context::this</tt>
|
||||
will always be the last context created. <i>Currently, this is where JS
|
||||
API function that require contexts get it.</i>
|
||||
<h4>
|
||||
<a NAME="Installation"></a>PerlConnect Installation</h4>
|
||||
PerlConnect requires <tt>js/src</tt> and the Perl libraries and headers.
|
||||
The only <tt>js/src</tt> file that must be included in <tt>jsapi.h </tt>in
|
||||
the top level directory. You need to compile it together with Perl libraries.
|
||||
Referer to the <tt>perlembed</tt> man page for more details.
|
||||
<br><b>On WINNT:</b>
|
||||
<br>There are MSDEV Workspace and project files in the main PerlConnect
|
||||
directory. There are three projects included in the PerlConnect workspace:
|
||||
JS, PerlConnect and PerlConnectShell. You can use the latter to test PerlConnect.
|
||||
You will probably need to adjust the library and include paths. Set PERL_SRC
|
||||
environment variable to point to the directory where you unpacked and compiled
|
||||
Perl sources. It is assumed that the directory structure is more or less
|
||||
fixed, that is, you have PerlConnect in
|
||||
<tt>js/src/perlconnect</tt>. PerlConnect
|
||||
project produces <tt>PerlConnect.dll</tt>, you should make sure it and
|
||||
<tt>perl.dll</tt> are in your path for PerlConnectShell to work.
|
||||
<p>JS also builds a DLL, <tt>JS.dll</tt> which is supposed to reside where
|
||||
Perl's DynaLoader can find it. On my machine I put it under <tt>c:\perl\lib\auto\JS\JS.dll</tt>.
|
||||
You can also put it in <tt>c:\perl\lib\</tt>. You can probably adjust PERLLIB
|
||||
to archieve the desired result. See Perl's DynaLoader documentation for
|
||||
more info on how dynamic libraries are found.
|
||||
<p><b>On UNIX:</b>
|
||||
<br>We are currently working on a UNIX makefile. Please <a href="mailto:val4@cornell.edu">contact
|
||||
me</a> for more details.
|
||||
<h4>
|
||||
On the MAC:</h4>
|
||||
We never really thought of supporting the Mac. If anyone is really interested
|
||||
in seeing Mac support, <a href="mailto:val4@cornell.edu">drop me a line</a>.
|
||||
<h4>
|
||||
<a NAME="Limitations"></a>Current Limitations and Futher Work</h4>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
Perl variables currently can't be assigned to, that is, <tt>p["$a"]=100</tt>
|
||||
doesn't do anything.</li>
|
||||
|
||||
<li>
|
||||
You can only have one interpreter running at a time. Despite the fact that
|
||||
you can create multiple Perl objects on JavaScript, they all share the
|
||||
same namespace. We can probably use <tt>Safe.pm</tt> to implement independent
|
||||
namespaces.</li>
|
||||
|
||||
<li>
|
||||
Module names resolution reports an error only when you try to evaluate
|
||||
the last element of the resolution chain. Here is what I mean: if you reference
|
||||
<tt>p.Foo.Bar.Var</tt> and <tt>For</tt> or <tt>Bar</tt> don't exist, it
|
||||
will only complain that p.Foo.Bar.Var is not a valid variable. Perl 5.005
|
||||
provides <tt>exists Foo::{Bar::}</tt> to check if Foo::Bar is a valid package.</li>
|
||||
|
||||
<li>
|
||||
Dynamic loading of the Perl interpreter only if it is required.</li>
|
||||
|
||||
<li>
|
||||
Recursive printing of Perl's arrays and hashes can be added. See Data::Dumper.pm</li>
|
||||
|
||||
<li>
|
||||
Full support for tied hashes and arrays in Perl</li>
|
||||
|
||||
<li>
|
||||
Calling JavaScript functions and accessing variables from Perl. JavaScript
|
||||
calling syntax support using AUTOLOADing.</li>
|
||||
|
||||
<li>
|
||||
JS can be made a directory with <tt>Object.pm</tt>, <tt>Context.pm</tt>,
|
||||
etc. in it. See how C or Tk are organized on CPAN</li>
|
||||
|
||||
<li>
|
||||
Distribution model for JS.pm. Perl provides something by default. See <tt>h2xs</tt>
|
||||
man page, for example.</li>
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче