Forum: Ruby a most undangerous Hash#store!

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-07 23:43
(Received via mailing list)
Hi--

Think I need a better name for this method. It is anything but
dangerous. Any ideas?

  # As with #store but adds the key/value pair
  # only if the key isn't already in the hash.

  def store!(key, value)
    unless key?(key)
      store(key,value)
      return value
    end
  end

T.
1b5341b64f7ce0244366eae17f06c801?d=identicon&s=25 unknown (Guest)
on 2007-01-08 01:02
(Received via mailing list)
On Mon, 8 Jan 2007, Trans wrote:

>    end
>  end

store_once ?


Kirk Haines
5da4c52f43677f395aff5bde775593c2?d=identicon&s=25 Daniel Schierbeck (dasch)
on 2007-01-08 01:20
(Received via mailing list)
On Mon, 2007-01-08 at 07:42 +0900, Trans wrote:
>       store(key,value)
>       return value
>     end
>   end

Is there really a need for such a method? Why not simply:

  hsh[:key] ||= "value"

or, if you have a default value on your hash:

  hsh[:key] = "value" unless hsh.has_key? :key

I'm positive you've thought about this, but I cannot find a reason why
such a method should be necessary.


Cheers,
Daniel
918c6daad03c85e51ad1a11f57017947?d=identicon&s=25 Devin Mullins (twifkak)
on 2007-01-08 01:23
(Received via mailing list)
Trans wrote:
>   # As with #store but adds the key/value pair
>   # only if the key isn't already in the hash.
Hrm. ActiveSupport has something similar. You can do
hash.reverse_merge(key => value).

HNTH,
Devin
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-08 01:48
(Received via mailing list)
Daniel Schierbeck wrote:

> Is there really a need for such a method? Why not simply:
>
>   hsh[:key] ||= "value"

This isn't quite the same becasue it looks to see if tha value is nil
or false, not if the key is there or not.

> or, if you have a default value on your hash:
>
>   hsh[:key] = "value" unless hsh.has_key? :key

Yes, certianly. nad that woul dbe fine if I were just needing here and
ther, but I have need for using it quite often.

> I'm positive you've thought about this, but I cannot find a reason why
> such a method should be necessary.

HTH,
T.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-08 02:00
(Received via mailing list)
Hi --

On Mon, 8 Jan 2007, Trans wrote:

>> or, if you have a default value on your hash:
>>
>>   hsh[:key] = "value" unless hsh.has_key? :key
>
> Yes, certianly. nad that woul dbe fine if I were just needing here and
> ther, but I have need for using it quite often.

You can use merge and a one-key hash:

   hash.merge({ :key => "new value" })


David
E0ed615bd6632dd23165e045e3c1df09?d=identicon&s=25 Florian Gross (Guest)
on 2007-01-08 02:15
(Received via mailing list)
On 2007-01-08 02:00:10 +0100, dblack@wobblini.net said:

> hsh[:key] = "value" unless hsh.has_key? :key
> You can use merge and a one-key hash:
>
>    hash.merge({ :key => "new value" })

Hm, not really:

{ :key => "old value" }.merge({ :key => "new value" }) # => {:key=>"new
value"}
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-08 02:49
(Received via mailing list)
Devin Mullins wrote:
> Trans wrote:
> >   # As with #store but adds the key/value pair
> >   # only if the key isn't already in the hash.
> Hrm. ActiveSupport has something similar. You can do
> hash.reverse_merge(key => value).

Astute! Indeed, I am using that too. Though I defined an operator for
it instead:

  hash *= {key=>value}

(I use + as an alias for regular merge, btw.) In general though I would
prefer a simple conditional store method b/c it's (probably) more
efficient for a small numbers of entries and it also reads better.

T.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-08 02:59
(Received via mailing list)
Hi --

On Mon, 8 Jan 2007, Florian Gross wrote:

> value"}
True -- that's a bit of a deal-breaker :-)


David
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-08 03:00
(Received via mailing list)
Trans wrote:
>   hash *= {key=>value}

Hmm... it just occured to me that maybe this would be better defined
as:

   hash |= {key=>value}

T.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-08 03:04
(Received via mailing list)
khaines@enigo.com wrote:

> store_once ?

That's pretty good. If nothing better come up I'll use that. Thanks.

T.
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2007-01-08 04:50
(Received via mailing list)
Trans wrote:
>       store(key,value)
>       return value
>     end
>   end
>
> T.

new_item
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-01-08 05:13
(Received via mailing list)
Trans [mailto:transfire@gmail.com] :

#   # As with #store but adds the key/value pair
#   # only if the key isn't already in the hash.

just a suggestion: *not another new method name (since we're still
updating/merging, right?). just add an option  --if possible ie

merge :nodup
update :nodup

merge require => :nodup
update require => :nodup

merge :safe
update :safe

merge require => :safe
update require => :safe
Ae16cb4f6d78e485b04ce1e821592ae5?d=identicon&s=25 Martin DeMello (Guest)
on 2007-01-08 06:34
(Received via mailing list)
On 1/8/07, Trans <transfire@gmail.com> wrote:
> Hi--
>
> Think I need a better name for this method. It is anything but
> dangerous. Any ideas?
>
>   # As with #store but adds the key/value pair
>   # only if the key isn't already in the hash.

#underlay

martin
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-08 12:15
(Received via mailing list)
On 08.01.2007 02:00, dblack@wobblini.net wrote:
>>
> You can use merge and a one-key hash:
>
>   hash.merge({ :key => "new value" })

Or even

hash.merge( :key => "new value" )

  robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-08 12:21
(Received via mailing list)
On 08.01.2007 02:59, dblack@wobblini.net wrote:
>>
>> Hm, not really:
>>
>> { :key => "old value" }.merge({ :key => "new value" }) # =>
>> {:key=>"new value"}
>
> True -- that's a bit of a deal-breaker :-)

But only if you need the return value:

irb(main):001:0> hash={:key=>1}
=> {:key=>1}
irb(main):002:0> hash.merge( :key => "new value" )
=> {:key=>"new value"}
irb(main):003:0> hash
=> {:key=>1}

The hash is merged properly.

  robert
Dd76a12d66f843de5c5f8782668e7127?d=identicon&s=25 Mauricio Fernandez (Guest)
on 2007-01-08 13:25
(Received via mailing list)
On Mon, Jan 08, 2007 at 08:20:05PM +0900, Robert Klemme wrote:
> >>
> => {:key=>"new value"}
> irb(main):003:0> hash
> => {:key=>1}
>
> The hash is merged properly.

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

a = {}
a.merge(:foo => 1)        # => {:foo=>1}
a                         # => {}
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-01-08 13:37
(Received via mailing list)
Hi --

On Mon, 8 Jan 2007, Mauricio Fernandez wrote:

>>>> Hm, not really:
>> irb(main):002:0> hash.merge( :key => "new value" )
> a.merge(:foo => 1)        # => {:foo=>1}
> a                         # => {}

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


David
1f866d114b0e32f3dbfe70cf9701ea6e?d=identicon&s=25 Kai Nitschke (Guest)
on 2007-01-08 14:41
(Received via mailing list)
khaines@enigo.com schrieb:
>>      store(key,value)
>>      return value
>>    end
>>  end
>
> store_once ?
>

how about store_unique ?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-01-08 15:00
(Received via mailing list)
On 08.01.2007 13:37, dblack@wobblini.net wrote:
> Yes, merge was just a wrong turn on my part.  Forget it.

Done.  And sorry for the noise (*my* noise that is).

Kind regards

  robert
Dd76a12d66f843de5c5f8782668e7127?d=identicon&s=25 Mauricio Fernandez (Guest)
on 2007-01-08 15:45
(Received via mailing list)
On Mon, Jan 08, 2007 at 09:37:05PM +0900, dblack@wobblini.net 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...
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-01-08 16:34
(Received via mailing list)
On 1/8/07, Mauricio Fernandez <mfp@acm.org> wrote:
>
> <snip>




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 ;)

    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 Fernandez  -   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
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-09 02:47
(Received via mailing list)
Mauricio Fernandez 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.
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-01-09 11:06
(Received via mailing list)
On 1/9/07, Trans <transfire@gmail.com> 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
Dd76a12d66f843de5c5f8782668e7127?d=identicon&s=25 Mauricio Fernandez (Guest)
on 2007-01-10 20:06
(Received via mailing list)
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.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-01-19 16:30
(Received via mailing list)
Mauricio Fernandez 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.
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-09-25 22:29
(Received via mailing list)
On 1/13/07, Martin DeMello <martindemello@gmail.com> 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 ;)

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 :(
-
its call syntax for the special behavior makes it quite readable.

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

Robert
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2007-09-25 22:34
(Received via mailing list)
Martin DeMello wrote:
> On 1/13/07, Mauricio Fernandez <mfp@acm.org> 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.
Dd76a12d66f843de5c5f8782668e7127?d=identicon&s=25 Mauricio Fernandez (Guest)
on 2007-09-25 22:39
(Received via mailing list)
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)
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2007-09-25 22:39
(Received via mailing list)
On 1/13/07, Robert Dober <robert.dober@gmail.com> 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?
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-09-25 22:50
(Received via mailing list)
On 1/13/07, Wilson Bilkovich <wilsonb@gmail.com> 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
Ae16cb4f6d78e485b04ce1e821592ae5?d=identicon&s=25 Martin DeMello (Guest)
on 2007-09-25 22:51
(Received via mailing list)
On 1/13/07, Mauricio Fernandez <mfp@acm.org> 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
This topic is locked and can not be replied to.