From: Sylvain LE G. <syl...@po...> - 2004-01-31 02:23:19
|
Hello all, Sometimes ago we were discussing about a possible library manipulation filename and files. I have almost created it. I think it is pretty stable but i need extended testing on different filename, and an expert eye on my code. You can find documentation and tarball here : http://www.gallu.homelinux.org/~gildor/ocaml-fileutils/ I wait for any of your comment on this code. If you think some functions should be added, just tell me, or better send a bug report to su...@bu... ( see README in the tarball to know exactly the text that must precede the bug report ). Features : Filename : - reduce "a/../b" -> "b" - make absolute filename - make relative filename - reparent a filename=20 ( a pair of others but not very interesting ). Files : - test - mv - cp - rm - find - mkdir - which - list_dir I hope it will be usefull for you. If you think the library is enough stable, just tell me... I will make a public announcement. Kind regard Sylvain LE GALL |
From: Nicolas C. <war...@fr...> - 2004-02-01 09:49:40
|
> Sometimes ago we were discussing about a possible library manipulation > filename and files. > > I have almost created it. I think it is pretty stable but i need > extended testing on different filename, and an expert eye on my code. > > You can find documentation and tarball here : > http://www.gallu.homelinux.org/~gildor/ocaml-fileutils/ Hello, I had a look at SysPath. My first thoughs were that it's too much complex. It seems that in order to have multi OS library, you used several language features such as Functors , as well as a lexer plus a yacc parser for each system in order to parsing the paths. IMHO it's too heavyweight and the small differences ( drive letter and / against \ ) in path representation between systems should be handled with a maximal transparency. Using functors to abstract something is nice if you're expecting the future users of your library to have the will to extend it further. I don't think it applies to this problem, since we already know well the 3-4 differents systems ( Unix , MacOS, Windows, Cygwin-? ) and there is an almost-zero probability that another system using a different path representation will be added to this list in the future... Using a lexer and a yacc parser for parsing such easy things as paths is also - still IMHO - using a hammer to kick a mosquito. A simple custom lexer/parser such as the one I proposed in my original post should be enough and perhaps provide even better speed. In order to be KISS-compliant, I advise you to rewrote the whole SysPath using only one file and module. SysUtil looks very good, I have no complaints about it :) Regards, Nicolas Cannasse |
From: <syl...@po...> - 2004-02-01 12:55:06
|
Hello, On Sun, Feb 01, 2004 at 10:54:27AM +0100, Nicolas Cannasse wrote: > > Sometimes ago we were discussing about a possible library manipulation > > filename and files. > > > > I have almost created it. I think it is pretty stable but i need > > extended testing on different filename, and an expert eye on my code. > > > > You can find documentation and tarball here : > > http://www.gallu.homelinux.org/~gildor/ocaml-fileutils/ > > Hello, > > I had a look at SysPath. My first thoughs were that it's too much complex. > It seems that in order to have multi OS library, you used several language > features such as Functors , as well as a lexer plus a yacc parser for each > system in order to parsing the paths. IMHO it's too heavyweight and the > small differences ( drive letter and / against \ ) in path representation > between systems should be handled with a maximal transparency. > > Using functors to abstract something is nice if you're expecting the future > users of your library to have the will to extend it further. I don't think > it applies to this problem, since we already know well the 3-4 differents > systems ( Unix , MacOS, Windows, Cygwin-? ) and there is an almost-zero > probability that another system using a different path representation will > be added to this list in the future... > > Using a lexer and a yacc parser for parsing such easy things as paths is > also - still IMHO - using a hammer to kick a mosquito. A simple custom > lexer/parser such as the one I proposed in my original post should be enough > and perhaps provide even better speed. > In order to be KISS-compliant, I advise you to rewrote the whole SysPath > using only one file and module. Well, OK. You are right about the fact that is a bit complicated. However, the difference doesn't lie only in separator. For example : MacOS ":a" means for unix "./a" and "::a" means "./../a"... For MacOS theres separator are context dependent. So i cannot apply simple regexp for doing filename split... I can analyze the string and adapt it to my need with String ( just like original implementation of Flename ). But it is as heavy as lex/yacc. There is also the problem of escaped char... To my mind, lex/yacc is kiss compliant. But it is only a point of view ( i use frequently this kind of construct because most of the time, when i do a custom parser/lexer, it always finish to block me when i try to extend it in any direction ). Concerning the speed, i think there is no real difference between custom parser and yacc parser ( i will tend to think that it is faster with yacc than with a custom parser ). The code by itself (yacc+lex+interface)x(win32,unix,macOs,cygwin) + sysPath.ml sysUtil.ml is not very long... And each module is KISS compliant. If i merge all in one file, i will have something too complicated. Concerning other implementation, i think that one day i will add, some others possibility, like URL et al. In fact, i think we do not agree on one thing : path and filename are complicated too me -- maybe i am silly. You need to take in account a lot of things to deals with this kind of things. > > SysUtil looks very good, I have no complaints about it :) > At least, there is one good things ;-) > Regards, > Nicolas Cannasse > Thanks for the report. Kind regard Sylvain LE GALL |
From: Nicolas C. <war...@fr...> - 2004-02-01 10:17:26
|
Just a little additionnal suggestion about SysUtil : SysUtil is heavily relying on the Unix module for its implementation, and that's ok. But only one feature ( the Match pattern to match the filename using a regexp) is using the Str module. In order to reduce dependencies, I think you should abstract the Match, using an user define regexp matching. For exemple : in SysUtil.mli : --- val configure_regexp : make:(string -> 'a) -> test:('a -> bool) -> unit in SysUtil.ml : ----- let regexp_make= ref (fun _ -> failwith "Regexp is not configured") let regexp_test = ref (fun x _ -> failwith "Regexp is not configured"; x = 0) (* we need to give a type here for ungeneralized variables *) let configure_regexp ~make ~test = regexp_make := Obj.magic make; (* we need to cast here because the type we need is slighty different *) regexp_test := Obj.magic test * and in testing Match : let reg = !regexp_make str in fun x -> !regexp_test reg x Then the user could write : SysUtil.configure_regexp Str.regexp Str.string_match before making any Match ( we can also use only one function with currying trick : SysUtil.configure_regexp (fun reg -> let reg = Str.regexp reg in (Str.String.match reg)) but it's then less comprehensible for the user ) Regards, Nicolas Cannasse |
From: <syl...@po...> - 2004-02-01 12:58:46
|
Hello, On Sun, Feb 01, 2004 at 11:22:14AM +0100, Nicolas Cannasse wrote: > Just a little additionnal suggestion about SysUtil : > > SysUtil is heavily relying on the Unix module for its implementation, and > that's ok. But only one feature ( the Match pattern to match the filename > using a regexp) is using the Str module. In order to reduce dependencies, I > think you should abstract the Match, using an user define regexp matching. > For exemple : > > in SysUtil.mli : > --- > > val configure_regexp : make:(string -> 'a) -> test:('a -> bool) -> unit > > in SysUtil.ml : > ----- > let regexp_make= ref (fun _ -> failwith "Regexp is not configured") > let regexp_test = ref (fun x _ -> failwith "Regexp is not configured"; x = > 0) (* we need to give a type here for ungeneralized variables *) > > let configure_regexp ~make ~test = > regexp_make := Obj.magic make; (* we need to cast here because the type > we need is slighty different *) > regexp_test := Obj.magic test > > * and in testing Match : > let reg = !regexp_make str in > fun x -> !regexp_test reg x > > Then the user could write : > > SysUtil.configure_regexp Str.regexp Str.string_match > before making any Match > > ( we can also use only one function with currying trick : > SysUtil.configure_regexp (fun reg -> let reg = Str.regexp reg in > (Str.String.match reg)) > but it's then less comprehensible for the user ) > > Regards, > Nicolas Cannasse > > > Ok, you are perfectly right. I will remove the Str test and replace it by a user provided test... But i won't use obj.magic to cast regexp... I prefer let the user do some more work to have something fully ocaml compliant than using a clever trick that is not documented ( personnal point of view on obj.magic ). Thank you for your remark. Kind regard Sylvain LE GALL |