On Saturday, January 07, 2012 15:06:30 Ali Çehreli wrote: > On 01/07/2012 02:11 PM, RenatoL wrote: > > Very quick question > > > > import std.stdio; > > void main() > > { > > > > auto arr1 = ["uno":1, "due":2, "tre":3]; > > arr1.remove("xxx"); > > > > } > > > > also in this case the compiler does not say anything and the > > program goes out silently ... why? Would not it be better if an > > exception was raised? > > I think that could be a valid design choice. On the other hand, since > what is required is to remove the element, it is not really an error if > the object is already missing. The requirement is met. > > > After all if i write: > > > > writeln(arr1["xxx"]); > > > > runtime expresses its disappointment... > > You get the exception more simply by this: > > auto e = arr1["xxx"]; > > But that's understandable because the [] operator is supposed to provide > access to a usable object. Since there is no general concept of a null > object, there is no object to provide access to, so there is nothing > else to do but to throw.
You likely know this, but I'll point it out in case a newbie to decide to get htrowing behavior out of the substript operator. If the element is not in the container, then the subscript operator throws a RangeError if -release isn't used, so it's an Error, not an Exception, and isn't a Throwable that you're supposed to catch (since the unwinding of the stack skips destructors, scope statements, finall blocks for any Throwables which aren't either Exception or derived from Exception). Also, without - release, it does no bounds checking and will likely result in a segfault. So, relying on the subscript operator throwing is a _bad_ idea. The idea is that you never give it something that isn't actually in the container. If you need to check it, and you're dealing with a dynamic or static array, then you check the array's length. If you're dealing with an associative array, then you use the in operator to get a pointer to the element from the container and check whether it's null or not (since if it's null, it wasn't there). It would probably make remove more expensive if it had to throw when it didn't find an element, and for the most part, it's rather meaningless whether it was in the container before that. As pointed out, remove makes sure that the element is no longer in the container after it's been called. It has no real reason to care whether an element was in there before or not. And if _you_ don't care, then being forced to check whether an element was in the container before trying to remove it would make your code less efficient. The way remove is now, the check only occurs if you do it yourself and therefore actually _want_ it. And odds are, such a check would be an assertion anyway (and therefore would be throwing an AssertError on failure, not an Exception), since the fact that the element wasn't in there anymore is a bug in your code, since your code is assuming that it's there. So, while I can understand someone's first reaction being why remove doesn't throw if the element isn't there, when you really think through it, it does make more sense for it not to throw. - Jonathan M Davis