From: rich Date: Thu, 16 Oct 2003 13:41:06 +0000 (+0000) Subject: Added ocamldoc, and fixed bugs. X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;h=885e4318d7a5540f55c3c78c03222f6d9fb6a70f;p=perl4caml.git Added ocamldoc, and fixed bugs. Added tutorial on writing wrappers. Fixed bug in LWP::UserAgent->request (was calling wrong method). --- diff --git a/.cvsignore b/.cvsignore index 46ba5bc..aa3da54 100644 --- a/.cvsignore +++ b/.cvsignore @@ -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 diff --git a/Makefile b/Makefile index d09c8dc..711cbce 100644 --- 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 --- 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 index 0000000..301f631 --- /dev/null +++ b/doc/writing-a-wrapper.html @@ -0,0 +1,385 @@ + + + + Writing a high-level wrapper around a Perl library + + + + +

Writing a high-level wrapper around a Perl library

+ +

+ This document discusses the theory and practice behind writing + a wrapper around a typical object-oriented Perl library. We + use Pl_LWP_UserAgent + as an example. (This is the high-level wrapper around the + LWP::UserAgent + library). +

+ +

+ 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 + perl4caml + development. +

+ +

First steps

+ +

+ I'm going to use LWP::UserAgent + 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: +

+ +
+perldoc LWP::UserAgent
+
+ +

+ or follow + this link. +

+ +

Understanding what we're doing

+ +

+ The low-level Perl module offers + two useful functions and a useful datatype which we'll be using + extensively. The useful functions are: +

+ + + + + + + + + + + + + + + + + + + +
Function name Perl equivalent Description
call_class_method $obj = LWP::UserAgent->new (args...) +

Calls a static method or constructor on a class.

+
call_method $obj->some_method (args...) +

Calls an instance method on an object.

+
+ +

+ The useful datatype is called the Perl.sv (an + abstract type), which represents a scalar value in Perl (anything + you would normally write in Perl with a $, including + numbers, strings, references and blessed objects). To find out + more about "SVs" see the perlguts(3) man page. +

+ +

+ To see how these three things interact, let's create an + LWP::UserAgent object and call a method on it: +

+ +
+# #load "perl4caml.cma";;
+# open Perl;;
+# let sv = call_class_method "LWP::UserAgent" "new" [];;
+val sv : Perl.sv = <abstr>
+# let agent = call_method sv "agent" [];;
+val agent : Perl.sv = <abstr>
+# string_of_sv agent;;
+- : string = "libwww-perl/5.69"
+
+ +

+ Note how the variable sv contains the actual Perl + object (an instance of LWP::UserAgent). To be + quite clear, this is the equivalent of the following Perl code: +

+ +
+$sv = LWP::UserAgent->new ();
+$agent = $sv->agent ();
+print $agent;
+
+ +

+ 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 string_of_sv might fail if the SV + isn't actually a string); thirdly there are more pleasant ways + to present this interface. +

+ +

+ Writing a high-level wrapper around these low-level operations + is what is described in the rest of this document ... +

+ +

Classes and constructors

+ +

+ Our general plan, therefore, will be to create an OCaml class + corresponding to LWP::UserAgent, which hides the + implementation (the sv, the calls to + call_method, and the conversion of arguments + to and from SVs). We will also need to write one or more constructor + function. +

+ +

+ 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": +

+ +
+$ua->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.
+
+ +

+ becomes two methods in the OCaml version: +

+ +
+class lwp_useragent sv = object (self)
+  (* ... *)
+  method agent : string
+  method set_agent : string -> unit
+end
+
+ +

+ We will also write at least one function for every + constructor or static function exported from Perl. +

+ +

+ The OCaml object itself contains the sv which + corresponds to the Perl SV (ie. the actual Perl object). +

+ +

+ Here is the shape of our class: +

+ +
+(** Wrapper around Perl [LWP::UserAgent] class.
+  *
+  * Copyright (C) 20xx your_organisation
+  *
+  * $ Id $
+  *)
+
+open Perl
+
+let _ = eval "use LWP::UserAgent"
+
+class lwp_useragent sv = object (self)
+
+  The methods will go here ...
+
+end
+
+(* The "new" constructor. Note that "new" is a reserved word in OCaml. *)
+let new_ ... =
+  ...
+  let sv = call_class_method "LWP::UserAgent" "new" [args ...] in
+  new lwp_useragent sv
+
+Any other static functions will go here ...
+
+ +

+ Notice a few things here: +

+ +
    +
  1. There is some ocamldoc describing the class. +
  2. We "open Perl" to avoid having to prefix everything with + Perl.. +
  3. We eval "use LWP::UserAgent" when the module + is loaded. This is required by Perl. +
  4. The sv (scalar value representing the actual + object) is passed as a parameter to the class. +
+ +

Writing methods

+ +

Getters and setters

+ +

+ 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). +

+ +

+ Here's our getter and setter for the agent slot, described above. + The agent is a string: +

+ +
+  method agent =
+    string_of_sv (call_method sv "agent" [])
+  method set_agent v =
+    call_method_void sv "agent" [sv_of_string v]
+
+ +

+ Note: +

+ +
    +
  1. The get method is just called agent (not + "get_agent"). This is the standard for OCaml code. +
  2. We use string_of_sv and sv_of_string + 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. +
  3. The set method called call_method_void which + we haven't seen before. This is exactly the same as + call_method 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. +
+ +

+ Here's another example, with a boolean slot: +

+ +
+  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]
+
+ +

Ordinary methods

+ +

+ Other methods are perhaps simpler to wrap than getters and + setters. LWP::UserAgent contains an interesting + method called request (which actually runs the + request). +

+ +

+ What's particularly interesting about this method are the + parameter and return value. It takes an HTTP::Request + object and returns an HTTP::Response. +

+ +

+ I have already wrapped HTTP::Request and + HTTP::Response as modules + Pl_HTTP_Request and + Pl_HTTP_Response + respectively. You should go and look at the code in those + modules now. +

+ +

+ If request requires a parameter, what should that + parameter be? Naturally it should be the SV corresponding to + the HTTP::Request object. To get this, I provided + an #sv method on the http_request class. +

+ +

+ And what will request return? Naturally it will + return an SV which corresponds to the (newly created inside + Perl) HTTP::Response object. We need to wrap + this up and create a new OCaml http_response object, + containing that SV. +

+ +

+ This is what the final method looks like: +

+ +
+  method request (request : http_request) =
+    let sv = call_method sv "request" [request#sv] in
+    new http_response sv
+
+ +

+ It's actually not so complicated. +

+ +

Writing constructors and static functions

+ +

+ Constructors are fairly simple, although the new_ + function inside Pl_LWP_UserAgent is complicated + by the many optional arguments which LWP::UserAgent->new + can take. +

+ +

+ Here is the guts, omitting all but one of the optional args: +

+ +
+let new_ ?agent (* ... *) () =
+  let args = ref [] in
+  let may f = function None -> () | Some v -> f v in
+  may (fun v ->
+	 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
+
+ +

+ It works simply enough, first building up a list of svs + corresponding to the arguments, then calling + call_class_method to create the Perl object, then + returning a constructed OCaml lwp_useragent object + containing that sv. +

+ +

Contributing wrappers back to perl4caml

+ +

+ If you write a wrapper for a Perl class, particularly one from + CPAN, I urge you to + contribute it back to the perl4caml + development effort. Your contribution enriches the project + as a whole, and makes OCaml more useful too. +

+ +
+
Richard W.M. Jones
+ + +Last modified: Thu Oct 16 14:39:02 BST 2003 + + + diff --git a/perl.mli b/perl.mli index 36cb213..73270d2 100644 --- 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]. *) diff --git a/wrappers/pl_HTML_Element.ml b/wrappers/pl_HTML_Element.ml index c37a51d..a460416 100644 --- a/wrappers/pl_HTML_Element.ml +++ b/wrappers/pl_HTML_Element.ml @@ -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 diff --git a/wrappers/pl_HTML_Parser.ml b/wrappers/pl_HTML_Parser.ml index ec01e5f..ec58bb5 100644 --- a/wrappers/pl_HTML_Parser.ml +++ b/wrappers/pl_HTML_Parser.ml @@ -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 diff --git a/wrappers/pl_HTML_TreeBuilder.ml b/wrappers/pl_HTML_TreeBuilder.ml index 61e8a03..d9f090c 100644 --- a/wrappers/pl_HTML_TreeBuilder.ml +++ b/wrappers/pl_HTML_TreeBuilder.ml @@ -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 diff --git a/wrappers/pl_HTTP_Message.ml b/wrappers/pl_HTTP_Message.ml index 12d0ffc..0a51105 100644 --- a/wrappers/pl_HTTP_Message.ml +++ b/wrappers/pl_HTTP_Message.ml @@ -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 diff --git a/wrappers/pl_HTTP_Request.ml b/wrappers/pl_HTTP_Request.ml index 718c43a..e194956 100644 --- a/wrappers/pl_HTTP_Request.ml +++ b/wrappers/pl_HTTP_Request.ml @@ -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 diff --git a/wrappers/pl_HTTP_Response.ml b/wrappers/pl_HTTP_Response.ml index 806df91..19b6641 100644 --- a/wrappers/pl_HTTP_Response.ml +++ b/wrappers/pl_HTTP_Response.ml @@ -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 diff --git a/wrappers/pl_LWP_UserAgent.ml b/wrappers/pl_LWP_UserAgent.ml index 29fc7f4..c6a5b98 100644 --- a/wrappers/pl_LWP_UserAgent.ml +++ b/wrappers/pl_LWP_UserAgent.ml @@ -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" []) diff --git a/wrappers/pl_Net_Google.ml b/wrappers/pl_Net_Google.ml index 8c5a19b..5639d65 100644 --- a/wrappers/pl_Net_Google.ml +++ b/wrappers/pl_Net_Google.ml @@ -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 diff --git a/wrappers/pl_Net_Google_Cache.ml b/wrappers/pl_Net_Google_Cache.ml index 730482f..7f5d337 100644 --- a/wrappers/pl_Net_Google_Cache.ml +++ b/wrappers/pl_Net_Google_Cache.ml @@ -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 diff --git a/wrappers/pl_Net_Google_Response.ml b/wrappers/pl_Net_Google_Response.ml index 8e69538..4b54522 100644 --- a/wrappers/pl_Net_Google_Response.ml +++ b/wrappers/pl_Net_Google_Response.ml @@ -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 diff --git a/wrappers/pl_Net_Google_Search.ml b/wrappers/pl_Net_Google_Search.ml index 51ff941..d6178aa 100644 --- a/wrappers/pl_Net_Google_Search.ml +++ b/wrappers/pl_Net_Google_Search.ml @@ -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 diff --git a/wrappers/pl_Net_Google_Spelling.ml b/wrappers/pl_Net_Google_Spelling.ml index 6988e62..079f9e5 100644 --- a/wrappers/pl_Net_Google_Spelling.ml +++ b/wrappers/pl_Net_Google_Spelling.ml @@ -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 diff --git a/wrappers/pl_URI.ml b/wrappers/pl_URI.ml index 4c680be..fa4389f 100644 --- a/wrappers/pl_URI.ml +++ b/wrappers/pl_URI.ml @@ -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