From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id TAA09292; Fri, 6 Jun 2003 19:01:34 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id TAA09397 for ; Fri, 6 Jun 2003 19:01:33 +0200 (MET DST) Received: from aomori.annexia.org (annexia.force9.co.uk [212.56.101.183]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id h56H1WH24121 for ; Fri, 6 Jun 2003 19:01:32 +0200 (MET DST) Received: from rich by aomori.annexia.org with local (Exim 3.36 #1 (Debian)) id 19OKaq-0000j1-00 for ; Fri, 06 Jun 2003 18:01:32 +0100 Date: Fri, 6 Jun 2003 18:01:32 +0100 To: caml-list@inria.fr Subject: [Caml-list] Why do input* and readdir throw End_of_file ... annoying! Message-ID: <20030606170131.GA2769@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.4i From: Richard Jones X-Spam: no; 0.00; readdir:01 hides:01 closedir:01 opendir:01 pathname:01 argv:01 freshmeat:01 ltd:98 inefficient:01 ocaml:01 garbage:01 rec:01 filesystem:02 london:97 match:02 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Dear OCaml users, I'm pretty convinced that having the input* functions and readdir throw End_of_file when they run out of data is wrong. Instead 'readdir' (for example) should be prototyped as: readdir : dir_handle -> string option and the functions should return None when they run out of data. Either that or alternative forms which don't throw exceptions should be available. The reason is it makes input* and readdir very hard to use since they are throwing exceptions in what is essentially an un-exceptional case (it's _normal_, not exceptional, to keep reading data until the end of the stream). Take a look at the attached code. I've wrapped up 'readdir' in a function which hides the annoying exception (or course, this is inefficient, but I don't have much choice). The code is reasonably easy to understand. Please someone show me the elegant solution to this problem which doesn't involve hiding the exception ... An alternative would be, like Perl, to provide alternative forms of input_line and readdir (in particular) which return a list of lines/names in a single go, rather like: my @files = readdir DIR; in Perl. (Another minor point - do I need to call closedir, or will the garbage collector do that for me?) Rich. ---------------------------------------------------------------------- open Unix type filesystem = File of string | Directory of filesystem list;; let readdir_no_ex dirh = try Some (readdir dirh) with End_of_file -> None ;; let rec read_directory path = let dirh = opendir path in let rec loop () = let filename = readdir_no_ex dirh in match filename with None -> [] | Some "." -> loop () | Some ".." -> loop () | Some filename -> let pathname = path ^ "/" ^ filename in let stat = lstat pathname in let this = if stat.st_kind = S_DIR then Directory (read_directory pathname) else File pathname in this :: loop () in loop () ;; let path = Sys.argv.(1);; let fs = read_directory path;; -- Richard Jones, Red Hat Inc. (London) and Merjis Ltd. http://www.merjis.com/ http://www.annexia.org/ Freshmeat projects: http://freshmeat.net/users/rwmj NET::FTPSERVER is a full-featured, secure, configurable, database-backed FTP server written in Perl: http://www.annexia.org/freeware/netftpserver/ ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners