From: George Ogata Date: 2004-08-12T07:51:13+09:00 Subject: Re: empty? and size in Enumerable "Robert Klemme" writes: > "Kristof Bastiaensen" schrieb im Newsbeitrag > news:pan.2004.08.10.22.30.13.485476@vleeuwen.org... >> Hi, >> >> On Tue, 10 Aug 2004 23:11:43 +0200, Robert Klemme wrote: >> > class RandEnum >> > include Enumerable >> > >> > def each >> > rand(10).times { yield rand 20 } >> > self >> > end >> > end >> > >> >> That's all nice and esoteric, but I don't see why it is a >> reason against empty? or size. > > It is. Regard: > > if enum.empty? > puts "it's empty" > else > enum.each {|x| puts "found #{x}"} > end > > This code could not do what you expect because the properties empty? and > size would change between invocations. The guarantee, that each iteration > returns the same sequence of elements is just not part of the contract of > Enumerable. [...] > RandomEnum is not a pathological case, it's a completely legitimate > implementation that conforms to all that is expected from #each. And > while these kinds of implementations are not widely used I still don't > regard them esoteric. [...] > I've changed my mind here: the contract of Enumerable (or of #each if you > like) is too weak to guarantee a proper implementation of size and empty?. > The requirements on #each are really very weak and you can't provide a > proper size and empty? method for each classes using Enumerable. So IMHO > it's best to leave them out or put them in a separate module. What's a "proper implementation of size"? Is include?, min, any?, etc. implemented "properly" in these cases? Why not just take the meaning of #size as "same as `to_a.size' (assuming default #to_a)", or some such. Similar for #empty?, #each_index, #index, #join, and anything else in Array that can potentially be in Enumerable. This accomodates the common case, which is what we should be striving for, isn't it?