A most undangerous Hash#store!

On Mon, Jan 08, 2007 at 09:37:05PM +0900, [email protected] wrote:

The hash is merged properly.

The original hash is not modified by #merge.
#merge != #merge! (== #update)

a = {}
a.merge(:foo => 1) # => {:foo=>1}
a # => {}

Yes, merge was just a wrong turn on my part. Forget it.

To be fair, the reference to #merge was not entirely misguided, since

a = {:bar => 1, :foo => 2}
{:foo => 0}.merge(a) # => {:bar=>1, :foo=>2}
{:baz => 0}.merge(a) # => {:baz=>0, :bar=>1, :foo=>2}

It just happens to work the other way around (cf. #reverse_merge
mentioned
earlier in this thread).

Anyway, Trans was talking about destructive updates, so what about

def store?(key, value)
unless key?(key)
store(key,value)
return true
end
false
end

similar to the #store! he described, but with a more regular behavior
when you
have nil/false values…

On 1/8/07, Mauricio F. [email protected] wrote:

Anyway, Trans was talking about destructive updates, so what about

def store?(key, value)

make that store!? (I know you can’t) because I consider an updating
predicate dangerous, or were you just pulling our legs :wink:

unless key?(key)
  store(key,value)
  return true
end
false

end

similar to the #store! he described, but with a more regular behavior
when

you
have nil/false values…


Mauricio F. - http://eigenclass.org - singular Ruby

Robert

“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay

On 1/9/07, Trans [email protected] wrote:

end

a little more it makes sense – “is something stored with this key? if
not store this value with it”. i was also worried that it did not
return the stored value like the normal store, but i realize now that
could be ambigious if value=nil, so you may be on point. is that right?
if so then i have to go with your suggestion.

t.

Please reconsider making an updating predicate Tom! (no pun intended) I
was not joking above I really feel that is a very bad idea.

Your semantic interpretation of “?” makes sense but only without
consideration of the context of what all other “?” methods do.

Cheers
Robert

On Tue, Jan 09, 2007 at 10:46:20AM +0900, Trans wrote:

false

return the stored value like the normal store, but i realize now that
could be ambigious if value=nil, so you may be on point. is that right?

Yes, that’s the idea (“more regular behavior”), but as Robert said, a
predicate method with side-effects seems very dangerous (yes, store!?
would
be more accurate :).

So it might make sense to name it e.g. #store_once, with the above
semantics. Returning the value that was passed to the method makes
little
sense: it doesn’t provide any information we didn’t have to being with.

Mauricio F. wrote:

Yes, that’s the idea (“more regular behavior”), but as Robert said, a
predicate method with side-effects seems very dangerous (yes, store!? would
be more accurate :).

So it might make sense to name it e.g. #store_once, with the above
semantics. Returning the value that was passed to the method makes little
sense: it doesn’t provide any information we didn’t have to being with.

i agree. i will use that semantic but with a different name. after
further consideration I thought of:

insert(key,value)

i think its apt. argree?

t.

Mauricio F. wrote:

similar to the #store! he described, but with a more regular behavior when you
have nil/false values…

well, i was thinking of combining Mr. Haines idea with Mr. James to
get #store_new, which seemed just about right. but now your suggestion
is quite interesting. at first i wasn’t so sure, but thinking about it
a little more it makes sense – “is something stored with this key? if
not store this value with it”. i was also worried that it did not
return the stored value like the normal store, but i realize now that
could be ambigious if value=nil, so you may be on point. is that right?
if so then i have to go with your suggestion.

t.

On 1/13/07, Martin DeMello [email protected] wrote:

something already in the hash, it will mask the value you are trying
to add.

martin

I think that Tom’s idea to have a method doing what he suggests is a
bright
one, but we seem to fail to be able to find a convincing name, maybe in
that
case a different approach might be worth being considered.
Look at the following code, just for readability if something hits you
than
one could discuss philosophical issues :wink:

h.store(k, v, :overwrite => false)
h[k, :overwrite => false] = v
or
h[k, :noglobber ] = v
or
h.store(k, v, :globber => false)

Now you decide for yourself what is readable and define your conveniance
method in ::Hash.

For those strictly opposed to overcrowding the Hash#store interface and
they
have their points of course
although we are perfectly backward compatible

h.insert(k, v, :overwrite => false)
etc.etc.

Although insert is not a better name than before - it is not a bad name
anyway Tom, but I agree with Maurizio that it is just not good enough :frowning:

its call syntax for the special behavior makes it quite readable.

I guess I’ll file a RCR, JUST KIDDING!!!

Robert

On Fri, Jan 12, 2007 at 11:15:08AM +0900, Trans wrote:

further consideration I thought of:

insert(key,value)

i think its apt. argree?

The problem with that name is that there’s no indication of the “just
once”
semantics, is there? Instead, it makes one think of String#insert and
Array#insert, and wonder what #insert translates to in an unordered
container
(for instance, one interpretation would be that the value will be
pushed/unshifted to the array associated to the key, assuming that the
hash
holds arrays/sets).
So it adds to the list of things we have to memorize.

Do you feel that store_{once,new,unique} is too long?
(I have a slight preference for “once”; “unique” seems a bit puzzling
since it
seems to refer to the key, which is always unique)

Martin DeMello wrote:

On 1/13/07, Mauricio F. [email protected] wrote:

Do you feel that store_{once,new,unique} is too long?
(I have a slight preference for “once”; “unique” seems a bit puzzling since it
seems to refer to the key, which is always unique)

it’s okay. but i would prefer the best and most concise name reasonably
possible, of course.

Even ‘store_once’ seems to refer to the value rather than the pair,
which is why I like “underlay” - it suggests that if there is
something already in the hash, it will mask the value you are trying
to add.

ah, ‘underlay’ as opposed to ‘overwrite’. i see where you’re coming
from there. with #insert i was thinking about databases where insert is
used to add a record but not to modify it – ie. if the record key is
already present you can’t insert a new one.

i understand that ‘insert’ isn’t prefect though. i tend to prefer
keeping array and hash in sync for polymorphism’s sake, but #insert
just doesn’t have an array-like meaning since it isn’t ordered. but
maybe an even simpler tern would suffice – #add.

t.

On 1/13/07, Robert D. [email protected] wrote:

which is why I like “underlay” - it suggests that if there is
something already in the hash, it will mask the value you are trying
to add.

Can we please just agree to write:
hash[key] = value unless hash.key?(key)
I mean… how often do you do this?

On 1/13/07, Mauricio F. [email protected] wrote:

Do you feel that store_{once,new,unique} is too long?
(I have a slight preference for “once”; “unique” seems a bit puzzling since it
seems to refer to the key, which is always unique)

Even ‘store_once’ seems to refer to the value rather than the pair,
which is why I like “underlay” - it suggests that if there is
something already in the hash, it will mask the value you are trying
to add.

martin

On 1/13/07, Wilson B. [email protected] wrote:

seems to refer to the key, which is always unique)

Even ‘store_once’ seems to refer to the value rather than the pair,
which is why I like “underlay” - it suggests that if there is
something already in the hash, it will mask the value you are trying
to add.

Can we please just agree to write:
hash[key] = value unless hash.key?(key)
I mean… how often do you do this?

I think it is clear that I would like to have this feature so sorry for
replying anyway.
This would be more than a convenience method it would be autodocumenting
Hash even better, it would make its API clearer.

Somebody was saying in this thread, why do you not write
hash[key] ||= value
you and I know better of course but if one has to read code to see
hash[key]= value unless hash.key? key
one could think poor guy he does not even know about the “hash[key] ||=
value” idiom.
OTH if in rdoc one saw

Hash#insert_once(key, value)
sets value only if key is not in the hash already, pleas note that this
is
not the same as hash[key] ||= value as…

one would probably believe, no?

Cheers
Robert