I find the thread a bit confused in the sense Dictionary *new* at: x ifAbsentPut: y
does not make sense (is academic), because the new dictionary will never have x as a key. So why profile it and use that as reasoning?... whereas myDict at:x ifAbsentPut: y is more interesting. In my experience i am biased by the use of the message in the systems that already use it heavily...however it always feels that the use of ifAbsentXX is intentionally deferring some code because it expresses exceptional cases in the application logic. Especially if the block makes an object you don't want to be doing that every time and discarding the result irrespective of the presence of the key. It does not have to be expensive to make, just not good style near any kind of loop. I know some people that actually don't like the ifAbsentPut: [] variant. and prefer to be explicit, of the form (myDict includesKey: x) ifFalse: [ myDict at: x put: y] where y is either a simple value or some expression. here the test on the key has the same effect as expecting a block in the inline ifAbsentPut: [] . It makes both forms basically the same, with one being more compact if you prefer that. If ifAbsentPut: did not expect the block then i think it would be a bit odd because you would have to unroll the code in order to achieve the deferred case which i feel is more common. cheers, Mike On Tue, Oct 4, 2011 at 2:44 PM, Henrik Sperre Johansen <[email protected]> wrote: > On 04.10.2011 12:52, Mariano Martinez Peck wrote: > > Hi guys. If I tell you the selector is Dictionary >> #at:ifAbsentPut: what > would you expect the second parameter to be? the value. > So, one would do: > Dictionary new at: #foo ifAbsentPut: 4 > > But if you see Dictionary >> > > at: key ifAbsentPut: aBlock > "Return the value at the given key. > If key is not included in the receiver store the result > of evaluating aBlock as new value." > > ^ self at: key ifAbsent: [self at: key put: aBlock value] > > so it expects a Block. Ok, we are in Smalltalk, so implementing #value is > enough. > > Well..the previous example works, but only because we have an ugly Object >> > value that returns self. > If I put instances of subclasses from ProtoObjects (proxies), that do not > work anymore. > > So...my question is we do Dictionary at: #foo put: 4, why #at:ifAbsentPut: > expects a block and not directly the value? > > Sven's reasons are correct I think, it's for efficiency, and elegant lazy > initialization of a cache. > The same reasons will never hold true when using #at:put:. > > in which case I need a block instead of the value object directly ? > > In addition to when you want delayed computation, when you have value > objects who redefine/do not define #value ;) > > Cheers, > Henry >
