Added ocamldoc, and fixed bugs.
authorrich <rich>
Thu, 16 Oct 2003 13:41:06 +0000 (13:41 +0000)
committerrich <rich>
Thu, 16 Oct 2003 13:41:06 +0000 (13:41 +0000)
Added tutorial on writing wrappers.
Fixed bug in LWP::UserAgent->request (was calling wrong method).

18 files changed:
.cvsignore
Makefile
README
doc/writing-a-wrapper.html [new file with mode: 0644]
perl.mli
wrappers/pl_HTML_Element.ml
wrappers/pl_HTML_Parser.ml
wrappers/pl_HTML_TreeBuilder.ml
wrappers/pl_HTTP_Message.ml
wrappers/pl_HTTP_Request.ml
wrappers/pl_HTTP_Response.ml
wrappers/pl_LWP_UserAgent.ml
wrappers/pl_Net_Google.ml
wrappers/pl_Net_Google_Cache.ml
wrappers/pl_Net_Google_Response.ml
wrappers/pl_Net_Google_Search.ml
wrappers/pl_Net_Google_Spelling.ml
wrappers/pl_URI.ml

index 46ba5bc..aa3da54 100644 (file)
@@ -3,4 +3,5 @@
 *.cmx
 *.cma
 *.cmxa
-perl4caml-*.tar.gz
\ No newline at end of file
+perl4caml-*.tar.gz
+html
\ No newline at end of file
index d09c8dc..711cbce 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Interface to Perl from OCaml.
 # Copyright (C) 2003 Merjis Ltd.
-# $Id: Makefile,v 1.10 2003-10-15 16:51:12 rich Exp $
+# $Id: Makefile,v 1.11 2003-10-16 13:41:06 rich Exp $
 
 include Makefile.config
 
@@ -8,6 +8,7 @@ OCAMLC := ocamlc
 OCAMLOPT := ocamlopt
 OCAMLMKLIB := ocamlmklib
 OCAMLDEP := ocamldep
+OCAMLDOC := ocamldoc
 
 OCAMLCINCS := -I wrappers
 OCAMLOPTINCS := $(OCAMLCINCS)
@@ -25,6 +26,8 @@ LIBPERL := $(shell perl -MExtUtils::Embed -e ldopts)
 # `shell perl -MExtUtils::Embed -e ldopts'
 DYNALOADER_HACK := /usr/lib/perl/5.8.1/auto/DynaLoader/DynaLoader.a
 
+OCAMLDOCFLAGS := -html -stars -sort $(OCAMLCINCS)
+
 WRAPPERS := \
        wrappers/pl_Net_Google_Cache.cmo \
        wrappers/pl_Net_Google_Response.cmo \
@@ -40,7 +43,7 @@ WRAPPERS := \
        wrappers/pl_HTTP_Response.cmo \
        wrappers/pl_LWP_UserAgent.cmo
 
-all:   perl4caml.cma perl4caml.cmxa all-examples
+all:   perl4caml.cma perl4caml.cmxa all-examples html
 
 perl4caml.cma: perl.cmo perl_c.o $(WRAPPERS)
        $(OCAMLMKLIB) -o perl4caml $(LIBPERL) $^
@@ -133,4 +136,13 @@ check-manifest:
        diff -u .orig-manifest .check-manifest; \
        rm -f .orig-manifest .check-manifest
 
-.PHONY: depend dist check-manifest
\ No newline at end of file
+# Documentation.
+
+html:  html/index.html
+
+html/index.html: $(wildcard *.ml) $(wildcard *.mli) $(wildcard wrappers/*.ml)
+       rm -rf html
+       mkdir html
+       -$(OCAMLDOC) $(OCAMLDOCFLAGS) -d html $^
+
+.PHONY: depend dist check-manifest html
\ No newline at end of file
diff --git a/README b/README
index 98907ca..55762fb 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 perl4caml
 Copyright (C) 2003 Merjis Ltd. (http://www.merjis.com/)
-$Id: README,v 1.1 2003-10-14 16:46:13 rich Exp $
+$Id: README,v 1.2 2003-10-16 13:41:06 rich Exp $
 
 perl4caml allows you to use Perl code within Objective CAML (OCaml),
 thus neatly side-stepping the old problem with OCaml which was that it
@@ -28,3 +28,12 @@ mod_caml was mainly written by Richard W.M. Jones
 
 (5) Try some of the examples in the examples/ directory (some of these
     require that you have certain Perl modules installed).
+
+       Documentation
+       -------------
+
+See doc/ for some documentation.
+
+To build ocamldoc (automatically generated documentation for interfaces)
+type 'make html'. The output can be found by pointing your browser at
+'html/index.html'.
diff --git a/doc/writing-a-wrapper.html b/doc/writing-a-wrapper.html
new file mode 100644 (file)
index 0000000..301f631
--- /dev/null
@@ -0,0 +1,385 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>Writing a high-level wrapper around a Perl library</title>
+    <link rel="stylesheet" href="http://www.merjis.com/css/default.css"
+      type="text/css">
+  </head>
+
+  <body bgcolor="#ffffff">
+    <h1>Writing a high-level wrapper around a Perl library</h1>
+
+    <p>
+      This document discusses the theory and practice behind writing
+      a wrapper around a typical object-oriented Perl library. We
+      use <a href="../html/Pl_LWP_UserAgent.html">Pl_LWP_UserAgent</a>
+      as an example. (This is the high-level wrapper around the
+      <a href="http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm">LWP::UserAgent</a>
+      library).
+    </p>
+
+    <p>
+      Don't worry - writing wrappers is really not very hard at all. I
+      hope that you, the reader, will write some wrappers around your
+      favorite Perl libraries and contribute them back to
+      <a href="http://www.merjis.com/developers/perl4caml/">perl4caml</a>
+      development.
+    </p>
+
+    <h2>First steps</h2>
+
+    <p>
+      I'm going to use <a href="http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm">LWP::UserAgent</a>
+      as my example throughout this document. Substitute that for whatever
+      library you want to wrap up and call from OCaml.
+      First of all make sure you have the library installed and working
+      under Perl, and make sure you have the manual page for that
+      library in front of you:
+    </p>
+
+<pre>
+perldoc LWP::UserAgent
+</pre>
+
+    <p>
+      or <a href="http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm">follow
+       this link</a>.
+    </p>
+
+    <h2>Understanding what we're doing</h2>
+
+    <p>
+      The low-level <a href="../html/Perl.html">Perl</a> module offers
+      two useful functions and a useful datatype which we'll be using
+      extensively. The useful functions are:
+    </p>
+
+    <table class="table">
+       <tr>
+         <th> Function name </th>
+         <th> Perl equivalent </th>
+         <th> Description </th>
+       </tr>
+
+       <tr>
+         <td> <code>call_class_method</code> </td>
+         <td> <code>$obj&nbsp;=&nbsp;LWP::UserAgent-&gt;new&nbsp;(args...)</code> </td>
+         <td>
+           <p> Calls a static method or constructor on a class. </p>
+         </td>
+       </tr>
+
+       <tr>
+         <td> <code>call_method</code> </td>
+         <td> <code>$obj-&gt;some_method&nbsp;(args...)</code> </td>
+         <td>
+           <p> Calls an instance method on an object. </p>
+         </td>
+       </tr>
+    </table>
+
+    <p>
+      The useful datatype is called the <code>Perl.sv</code> (an
+      abstract type), which represents a scalar value in Perl (anything
+      you would normally write in Perl with a <code>$</code>, including
+      numbers, strings, references and blessed objects). To find out
+      more about "SVs" see <a href="http://www.perldoc.com/perl5.8.0/pod/perlguts.html">the perlguts(3) man page</a>.
+    </p>
+
+    <p>
+      To see how these three things interact, let's create an
+      <code>LWP::UserAgent</code> object and call a method on it:
+    </p>
+
+<pre>
+# #load "perl4caml.cma";;
+# open Perl;;
+# let sv = call_class_method "LWP::UserAgent" "new" [];;
+<i>val sv : Perl.sv = &lt;abstr&gt;</i>
+# let agent = call_method sv "agent" [];;
+<i>val agent : Perl.sv = &lt;abstr&gt;</i>
+# string_of_sv agent;;
+<i>- : string = "libwww-perl/5.69"</i>
+</pre>
+
+    <p>
+      Note how the variable <code>sv</code> contains the actual Perl
+      object (an instance of <code>LWP::UserAgent</code>).  To be
+      quite clear, this is the equivalent of the following Perl code:
+    </p>
+
+<pre>
+$sv = LWP::UserAgent-&gt;new ();
+$agent = $sv-&gt;agent ();
+print $agent;
+</pre>
+
+    <p>
+      You could actually just continue to use the low-level interface
+      to access Perl objects directly, but there are three problems with
+      this: firstly it's cumbersome because you have to continually
+      convert to and from SVs; secondly it's not type safe
+      (eg. calling <code>string_of_sv</code> might fail if the SV
+      isn't actually a string); thirdly there are more pleasant ways
+      to present this interface.
+    </p>
+
+    <p>
+      Writing a high-level wrapper around these low-level operations
+      is what is described in the rest of this document ...
+    </p>
+
+    <h2>Classes and constructors</h2>
+
+    <p>
+      Our general plan, therefore, will be to create an OCaml class
+      corresponding to <code>LWP::UserAgent</code>, which hides the
+      implementation (the <code>sv</code>, the calls to
+      <code>call_method</code>, and the conversion of arguments
+      to and from SVs). We will also need to write one or more constructor
+      function.
+    </p>
+
+    <p>
+      We will write at least one method for every method exported by
+      the Perl interface. Sometimes we'll write two methods for each
+      Perl method, as in the case where a Perl method is a "getter/setter":
+    </p>
+
+<pre>
+$ua-&gt;agent([$product_id])
+   Get/set the product token that is used to identify the user agent
+   on the network.  The agent value is sent as the "User-Agent" header
+   in the requests.
+</pre>
+
+    <p>
+      becomes two methods in the OCaml version:
+    </p>
+
+<pre>
+class lwp_useragent sv = object (self)
+  (* ... *)
+  method agent : string
+  method set_agent : string -&gt; unit
+end
+</pre>
+
+    <p>
+      We will also write at least one function for every
+      constructor or static function exported from Perl.
+    </p>
+
+    <p>
+      The OCaml object itself contains the <code>sv</code> which
+      corresponds to the Perl SV (ie. the actual Perl object).
+    </p>
+
+    <p>
+      Here is the shape of our class:
+    </p>
+
+<pre>
+(** Wrapper around Perl [LWP::UserAgent] class.
+  *
+  * Copyright (C) 20xx <i>your_organisation</i>
+  *
+  * $ Id $
+  *)
+
+open Perl
+
+let _ = eval "use LWP::UserAgent"
+
+class lwp_useragent sv = object (self)
+
+  <i>The methods will go here ...</i>
+
+end
+
+(* The "new" constructor. Note that "new" is a reserved word in OCaml. *)
+let new_ ... =
+  ...
+  let sv = call_class_method "LWP::UserAgent" "new" [<i>args ...</i>] in
+  new lwp_useragent sv
+
+<i>Any other static functions will go here ...</i>
+</pre>
+
+    <p>
+      Notice a few things here:
+    </p>
+
+    <ol>
+      <li> There is some ocamldoc describing the class.
+      <li> We "open Perl" to avoid having to prefix everything with
+       <code>Perl.</code>.
+      <li> We <code>eval "use LWP::UserAgent"</code> when the module
+       is loaded. This is required by Perl.
+      <li> The <code>sv</code> (scalar value representing the actual
+       object) is passed as a parameter to the class.
+    </ol>
+
+    <h2>Writing methods</h2>
+
+    <h3>Getters and setters</h3>
+
+    <p>
+      Of all types of methods, getters and setters are the easiest
+      to write. First of all, check the manual page to find out what
+      type the slot is. You'll need to write one get method and
+      one set method. (Rarely you'll find getters and setters which
+      are quasi-polymorphic, for instance they can take a string or
+      an arrayref. You'll need to think more deeply about these,
+      because they require one set method for each type, and the
+      get method can be complicated).
+    </p>
+
+    <p>
+      Here's our getter and setter for the agent slot, described above.
+      The agent is a string:
+    </p>
+
+<pre>
+  method agent =
+    string_of_sv (call_method sv "agent" [])
+  method set_agent v =
+    call_method_void sv "agent" [sv_of_string v]
+</pre>
+
+    <p>
+      Note:
+    </p>
+
+    <ol>
+      <li> The get method is just called <code>agent</code> (not
+       "get_agent"). This is the standard for OCaml code.
+      <li> We use <code>string_of_sv</code> and <code>sv_of_string</code>
+       to convert to and from SVs. This will ensure that the
+       class interface will have the correct type (string), and
+       thus be type safe as far as the calling code is concerned,
+       and also means the caller doesn't need to worry about
+       SVs.
+      <li> The set method called <code>call_method_void</code> which
+       we haven't seen before. This is exactly the same as
+       <code>call_method</code> except that the method is called
+       in a "void context" - in other words, any return value is
+       thrown away. This is slightly more efficient than ignoring
+       the return value.
+    </ol>
+
+    <p>
+      Here's another example, with a boolean slot:
+    </p>
+
+<pre>
+  method parse_head =
+    bool_of_sv (call_method sv "parse_head" [])
+  method set_parse_head v =
+    call_method_void sv "parse_head" [sv_of_bool v]
+</pre>
+
+    <h3>Ordinary methods</h3>
+
+    <p>
+      Other methods are perhaps simpler to wrap than getters and
+      setters. <code>LWP::UserAgent</code> contains an interesting
+      method called <code>request</code> (which actually runs the
+      request).
+    </p>
+
+    <p>
+      What's particularly interesting about this method are the
+      parameter and return value. It takes an <code>HTTP::Request</code>
+      object and returns an <code>HTTP::Response</code>.
+    </p>
+
+    <p>
+      I have already wrapped <code>HTTP::Request</code> and
+      <code>HTTP::Response</code> as modules
+      <a href="../html/Pl_HTTP_Request.html">Pl_HTTP_Request</a> and
+      <a href="../html/Pl_HTTP_Response.html">Pl_HTTP_Response</a>
+      respectively. You should go and look at the code in those
+      modules now.
+    </p>
+
+    <p>
+      If <code>request</code> requires a parameter, what should that
+      parameter be? Naturally it should be the SV corresponding to
+      the <code>HTTP::Request</code> object. To get this, I provided
+      an <code>#sv</code> method on the <code>http_request</code> class.
+    </p>
+
+    <p>
+      And what will <code>request</code> return? Naturally it will
+      return an SV which corresponds to the (newly created inside
+      Perl) <code>HTTP::Response</code> object. We need to wrap
+      this up and create a new OCaml <code>http_response</code> object,
+      <em>containing that SV</em>.
+    </p>
+
+    <p>
+      This is what the final method looks like:
+    </p>
+
+<pre>
+  method request (request : http_request) =
+    let sv = call_method sv "request" [request#sv] in
+    new http_response sv
+</pre>
+
+    <p>
+      It's actually not so complicated.
+    </p>
+
+    <h2>Writing constructors and static functions</h2>
+
+    <p>
+      Constructors are fairly simple, although the <code>new_</code>
+      function inside <code>Pl_LWP_UserAgent</code> is complicated
+      by the many optional arguments which <code>LWP::UserAgent-&gt;new</code>
+      can take.
+    </p>
+
+    <p>
+      Here is the guts, omitting all but one of the optional args:
+    </p>
+
+<pre>
+let new_ ?agent (* ... *) () =
+  let args = ref [] in
+  let may f = function None -&gt; () | Some v -&gt; f v in
+  may (fun v -&gt;
+        args := sv_of_string "agent" :: sv_of_string v :: !args) agent;
+(* ... *)
+  let sv = call_class_method "LWP::UserAgent" "new" !args in
+  new lwp_useragent sv
+</pre>
+
+    <p>
+      It works simply enough, first building up a list of <code>sv</code>s
+      corresponding to the arguments, then calling
+      <code>call_class_method</code> to create the Perl object, then
+      returning a constructed OCaml <code>lwp_useragent</code> object
+      containing that <code>sv</code>.
+    </p>
+
+    <h2>Contributing wrappers back to perl4caml</h2>
+
+    <p>
+      If you write a wrapper for a Perl class, particularly one from
+      <a href="http://www.cpan.org/">CPAN</a>, I urge you to
+      contribute it back to the <a
+      href="http://www.merjis.com/developers/perl4caml/">perl4caml</a>
+      development effort. Your contribution enriches the project
+      as a whole, and makes OCaml more useful too.
+    </p>
+
+    <hr>
+    <address><a href="mailto:rich@annexia.org">Richard W.M. Jones</a></address>
+<!-- Created: Thu Oct 16 13:36:59 BST 2003 -->
+<!-- hhmts start -->
+Last modified: Thu Oct 16 14:39:02 BST 2003
+<!-- hhmts end -->
+  </body>
+</html>
index 36cb213..73270d2 100644 (file)
--- a/perl.mli
+++ b/perl.mli
@@ -2,7 +2,7 @@
   *
   * Copyright (C) 2003 Merjis Ltd.
   *
-  * $Id: perl.mli,v 1.7 2003-10-16 08:54:56 rich Exp $
+  * $Id: perl.mli,v 1.8 2003-10-16 13:41:06 rich Exp $
   *)
 
 type t
@@ -115,10 +115,10 @@ val sv_false : unit -> sv
 (** Returns an [SV] which is false. *)
 val sv_yes : unit -> sv
 (** Returns Perl's internal [PL_sv_yes]. (There are some unresolved issues
-  * with using this, so use {!sv_true} instead). *)
+  * with using this, so use {!Perl.sv_true} instead). *)
 val sv_no : unit -> sv
 (** Returns Perl's internal [PL_sv_no]. (There are some unresolved issues
-  * with using this, so use {!sv_false} instead). *)
+  * with using this, so use {!Perl.sv_false} instead). *)
 
 (* Actually there are many more types defined than this ... *)
 type sv_t    = SVt_NULL
@@ -161,16 +161,17 @@ val av_empty : unit -> av
 val av_of_sv_list : sv list -> av
 (** Create an array from a list of [SVs]. *)
 val av_push : av -> sv -> unit
-(** Append the [SV] to the end of the array. Same as Perl [push @av, $sv]. *)
+(** Append the [SV] to the end of the array. Same as Perl
+  * [push \@av, $sv]. *)
 val av_pop : av -> sv
 (** Remove the [SV] at the end of the array and return it. Same as
-  * Perl [$sv = pop @av]. *)
+  * Perl [$sv = pop \@av]. *)
 val av_shift : av -> sv
 (** Remove the [SV] at the beginning of the array and return it. Same as
-  * Perl [$sv = shift @av]. *)
+  * Perl [$sv = shift \@av]. *)
 val av_unshift : av -> sv -> unit
 (** Prepend the [SV] to the start of the array. Same as Perl
-  * [unshift @av, $sv]. *)
+  * [unshift \@av, $sv]. *)
 val av_length : av -> int
 (** Return the length of the [AV]. *)
 val av_set : av -> int -> sv -> unit
@@ -178,9 +179,9 @@ val av_set : av -> int -> sv -> unit
 val av_get : av -> int -> sv
 (** Get the i'th element of the [AV]. *)
 val av_clear : av -> unit
-(** Remove all elements from the [AV]. Same as Perl [@av = ()]. *)
+(** Remove all elements from the [AV]. Same as Perl [\@av = ()]. *)
 val av_undef : av -> unit
-(** Delete the [AV] (and all elements in it). Same as Perl [undef @av]. *)
+(** Delete the [AV] (and all elements in it). Same as Perl [undef \@av]. *)
 val av_extend : av -> int -> unit
 (** Extend the [AV] so it contains at least [n+1] elements. *)
 val av_map : (sv -> 'a) -> av -> 'a list
@@ -198,13 +199,14 @@ val get_sv : ?create:bool -> string -> sv
   * this function will return the [SV] for [undef].
   *)
 val get_av : ?create:bool -> string -> av
-(** Same as {!get_sv} except will return and/or create [@a]. *)
+(** Same as {!Perl.get_sv} except will return and/or create [\@a]. *)
 
 val call : ?sv:sv -> ?fn:string -> sv list -> sv
 (** Call a Perl function in a scalar context, either by name (using the [?fn]
   * parameter) or by calling a string/CODEREF (using the [?sv] parameter).
   *
-  * Returns the Perl [SV] containing the result value. (See {!int_of_sv} etc.).
+  * Returns the Perl [SV] containing the result value. (See
+  * {!Perl.int_of_sv} etc.).
   *
   * If the Perl code calls [die] then this will throw [Perl_failure].
   *)
index c37a51d..a460416 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTML::Element class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTML_Element.ml,v 1.3 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTML::Element] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTML_Element.ml,v 1.4 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index ec01e5f..ec58bb5 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTML::Parser class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTML_Parser.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTML::Parser] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTML_Parser.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 61e8a03..d9f090c 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTML::TreeBuilder class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTML_TreeBuilder.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTML::TreeBuilder] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTML_TreeBuilder.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 12d0ffc..0a51105 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTTP::Message class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTTP_Message.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTTP::Message] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTTP_Message.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 718c43a..e194956 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTTP::Request class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTTP_Request.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTTP::Request] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTTP_Request.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 806df91..19b6641 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl HTTP::Response class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_HTTP_Response.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [HTTP::Response] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_HTTP_Response.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 29fc7f4..c6a5b98 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl LWP::UserAgent class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_LWP_UserAgent.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [LWP::UserAgent] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_LWP_UserAgent.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
@@ -18,7 +20,7 @@ object (self)
     let sv = call_method sv "simple_request" [request#sv] in
     new http_response sv
   method request (request : http_request) =
-    let sv = call_method sv "simple_request" [request#sv] in
+    let sv = call_method sv "request" [request#sv] in
     new http_response sv
   method agent =
     string_of_sv (call_method sv "agent" [])
index 8c5a19b..5639d65 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl Net::Google class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_Net_Google.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [Net::Google] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_Net_Google.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 730482f..7f5d337 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl Net::Google::Cache class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_Net_Google_Cache.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [Net::Google::Cache] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_Net_Google_Cache.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 8e69538..4b54522 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl Net::Google::Reponse class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_Net_Google_Response.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [Net::Google::Reponse] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_Net_Google_Response.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 51ff941..d6178aa 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl Net::Google::Search class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_Net_Google_Search.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [Net::Google::Search] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_Net_Google_Search.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 6988e62..079f9e5 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl Net::Google::Spelling class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_Net_Google_Spelling.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [Net::Google::Spelling] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_Net_Google_Spelling.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl
 
index 4c680be..fa4389f 100644 (file)
@@ -1,7 +1,9 @@
-(* Wrapper around Perl URI class.
- * Copyright (C) 2003 Merjis Ltd.
- * $Id: pl_URI.ml,v 1.2 2003-10-15 16:51:12 rich Exp $
- *)
+(** Wrapper around Perl [URI] class.
+  *
+  * Copyright (C) 2003 Merjis Ltd.
+  *
+  * $Id: pl_URI.ml,v 1.3 2003-10-16 13:41:07 rich Exp $
+  *)
 
 open Perl