From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 35401BBCA for ; Sun, 11 May 2008 16:35:24 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgwBAHugJkjVJFBbmWdsb2JhbACSCQEBAQEBCAUGCREDlwk X-IronPort-AV: E=Sophos;i="4.27,469,1204498800"; d="scan'208";a="12095188" Received: from mx-out.libertysurf.net (HELO mail.libertysurf.net) ([213.36.80.91]) by mail1-smtp-roc.national.inria.fr with ESMTP; 11 May 2008 16:35:24 +0200 Received: from [192.168.1.2] (91.168.186.177) by mail.libertysurf.net (7.3.118.8) id 47F1FEBB00D2E3C0; Sun, 11 May 2008 17:29:09 +0200 From: Florent Monnier Organization: l'Association Linux-Nantes To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Hashtbl.remove legal within Hashtbl.iter for the same hash table? Date: Sun, 11 May 2008 16:42:13 +0200 User-Agent: KMail/1.8.2 References: <87tzh5kxhl.fsf@linux-france.org> In-Reply-To: <87tzh5kxhl.fsf@linux-france.org> MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200805111642.14164.fmonnier@linux-nantes.fr.eu.org> Cc: David MENTRE X-Face: #L_Y84Xu>Uii")W[x~M|kDXQ"7%\'1D_ybO)a'+{"'/%k9)|Sp|OcG`x0rzWb/Z[]^2=YjB 4BVs.BzlQt]}bW<3(}hEogE*O^~7>gK"-|G[HjY{[/SO5S'hf\aNcc?<[$bSq.2o>Lw dp43:s|Qwm-9JBS1~J45M sh,'|6.4>3o4BI>+dH(5B47Cz6/cX3NZ^TG{ES Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; hashtbl:01 hashtbl:01 iter:01 hash:01 iter:01 hash:01 pred:01 printf:01 printf:01 enum:01 enum:01 ocaml:01 site-lib:01 pred:01 sdt:01 > Hello, Hello David, > Probably a newbie question but anyway: is it allowed to do a > Hashtbl.remove while doing a Hashtbl.iter on the same hash table? I don't know if it is legal, but at least it works: # let h = Hashtbl.create 8 ;; # for i = 0 to pred 8 do Hashtbl.add h i (char_of_int((int_of_char 'A') + i)) done ;; # Hashtbl.iter (fun i v -> if i = 3 then Hashtbl.remove h 5; Printf.printf " %d %c\n" i v) h ;; 0 A 1 B 2 C 3 D 4 E 6 G 7 H But perhaps is it implementation dependant, in which case another implementation could react in a different way... The ExtLib reacts in the same way than the standard one. > More precisely, at one point while doing a "Hashtbl.iter f h" my > function "f" is called with something like "f k v". Can I do a > "Hashtbl.remove h k" within the body of "f"? it seems to work too when we remove the current itered key (with both implementations) I don't know if this module was written with in mind to allow this behavior, but for what I understand from the manual : "in-place modification" should mean that this structure is purely imperative and that this behavior is "legal/allowed". ______ Perhaps a more sure method could be to get an enum from the hash table, and then iter on this enum (with the ExtLib), see below. With this method you are sure that *all* the keys will be itered, including the hidden contents, which is different than the previous example. Then you don't need to worry about a perhaps implementation dependant behavior. ocaml -I +/site-lib/extlib extLib.cma # open ExtLib ;; # open ExtHashtbl ;; # let h = Hashtbl.create 8 ;; # for i = 0 to pred 8 do Hashtbl.add h i (char_of_int((int_of_char 'A') + i)) done ;; (* this one would not appear with the sdt Hashtbl.iter ! *) # Hashtbl.add h 6 'Z' ;; # let iter_all_hashtbl f h = let keys = Hashtbl.keys h and vals = Hashtbl.values h in Enum.iter2 f keys vals ;; # let f i v = if i = 3 then Hashtbl.remove h 3; Printf.printf " %d %c\n" i v ;; # iter_all_hashtbl f h ;; 0 A 1 B 2 C 3 D 4 E 5 F 6 Z 6 G 7 H # iter_all_hashtbl f h ;; 0 A 1 B 2 C 4 E 5 F 6 Z 6 G 7 H -- Florent