From: Dmitry B. <db...@ma...> - 2003-04-19 09:28:42
|
"Nicolas Cannasse" <war...@fr...> writes: > Yes, the Enum module is quite more "abstract" then the Stream one, and has > differents goals. > BTW, about your "count" problem you HAVE TO return the lines count, because > for exemple Array.of_enum will require it to create the array before putting > elements inside. The solution is quite easy to do : when "count" is called > the first time, you're reading all remaining files and then have to modify > your Enum.t which will now iter on the builded list. This is almost what the > "Enum.force" is doing, but I modified its behavior so it can be used this > way. > > The problem is that you can't right now do a "force" in a count function > since you're have not yet any Enum.t to work on, but ok let's try : > Here's the code : > > let lines_enum ch = > let dummy = ref None in > let e = Enum.make > ~next:(fun () -> try input_line ch with End_of_file -> raise > Enum.No_more_elements) > ~count:(fun () -> match !dummy with None -> assert false | Some e -> > Enum.force e; Enum.count e) > in > dummy := e; > e It's OK for regular files, but what if you're reading something like socket or pipe that is endless by its nature? You usually look into the returned line and decide if it's enough. So maybe to parameterize your line_enum fuction the way like this: let lines_enum ?(is_eof=(fun s -> false)) ch = let dummy = ref None in let e = Enum.make ~next:(fun () -> try let line = input_line ch in if is_eof line then raise Enum.No_more_elements else line with End_of_file -> raise Enum.No_more_elements) ~count:(fun () -> match !dummy with None -> assert false | Some e -> Enum.force e; Enum.count e) in dummy := e; e Just an idea ... - Dmitry Bely |