On Mon, 10 Nov 2008, Mindaugas Kavaliauskas wrote: Hi Mindaugas,
> I'm just trying to made my understand about an answer to two questions: > 1) is it good that enumerators are detached to references to iterated items > (or is it better to remain it enumerators in the codeblocks)? If we left them as enumerator they will be updated by farther iterations and it will not be possible to detach given item. > 2) can it remain an enumerator in codeblocks? Can we implement it > technically? Or this is not possible because of current enumerators > implementation or some other side effects. We do not have such functionality now but it can be implemented. We will have to add support for reference counter to enumerators and unblock their copping but it's possible. The question is if we want to have such functionality. > PROC main() > LOCAL aCountry, aI, aJ, nI > > aCountry := {"LTU", "ZWE"} > aJ := {} > FOR nI := 1 TO LEN(aCountry) > aI := aCountry[nI] > AADD(aJ, {|| aI}) > NEXT > FOR nI := 1 TO LEN(aCountry) > ? EVAL(aJ[nI]) > NEXT > RETURN > But in this sample aI is not detached to current aI value, and sample > prints: > ZWE > ZWE > How can I easy understand/remember the difference between this behavior and > enumerators behavior? Just like now you have to remember that: FOR EACH aI IN aCountry aI := NIL NEXT will set NIL to all aCountry items. FOR and FOR EACH are different things. In FOR EACH iterator is reference to item. When this reference is detached it's not longer updated by next iterations. For me it's correct behavior. The only one problem I see here is the fact that comp;iler does not generate compile time warning for the code you send. It should. It's caused by side effect of simple codeblock implementation. When expressions are created compiler does not know that they are part of codeblock which is not allocated yet and finds aI as iterator in parent function. For extended codeblocks and simple aI:__enum*() usage warning message is correctly generated. F.e.: PROC main() LOCAL aCountry, aI, bc aCountry := {"LTU"=>"Lithuania", "ZWE"=>"Zimbabwe"} FOR EACH aI in aCountry QOUT(aI:__enumKey) // OK EVAL({|| QOUT(aI:__enumKey), asd asd}) // RTE bc:={||; return aI:__enumKey; } // WARNING NEXT QOUT(aI:__enumKey) // WARNING RETURN It should be fixed. To make it well we should change the method of codeblock creating in compiler but it's to small problem for me to invest time for it now. I'll make it in the future with some other modifications but now I can simply add new variable to FUNCTION structure to indicate that we are in simple codeblock context. I'll commit this modification in a while. Meanwhile you may think about expected behavior for other FOR EACH related contexts. F.e. please also remember that after leaving FOR EACH original enumerator value is restored, f.e.: aI := 1234.567 FOR EACH aI IN aCountry aI := NIL NEXT ? aI // 1234.567 It's original behavior implemented by Ryszard we still keep. If we begin to detach enumerators then after leaving FOR EACH detached enumerators should also point to original value (1234.567 in above example). Other method is declaring temporary local variables for enumerators and forbid using normal MEMVAR/STAATIC/LOCAL variables so the code will look like: proc p( aCountry ) for each aI in aCountry // aI is temporary local variable // allocated automatically by compiler ? aI next return best regards, Przemek _______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour