Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Special Hash Constructors

Reply
Thread Tools

Special Hash Constructors

 
 
Robert Klemme
Guest
Posts: n/a
 
      02-06-2009

Hi there,

we frequently do

ha = Hash.new {|h,k| h[k] = []}

so we can later do

ha[any_key] << anything

Since the idiom is so common, what does everybody think of putting it
into the standard library:

def Hash.with_arrays
new {|h,k| h[k] = []}
end

While we're at it, we might as well add

def Hash.with_hashes
new {|h,k| h[k] = Hash.new(&h.default_proc)}
end

Kind regards

robert
 
Reply With Quote
 
 
 
 
Christopher Dicely
Guest
Posts: n/a
 
      02-06-2009
On Fri, Feb 6, 2009 at 9:09 AM, Robert Klemme
<(E-Mail Removed)> wrote:
>
> Hi there,
>
> we frequently do
>
> ha = Hash.new {|h,k| h[k] = []}
>
> so we can later do
>
> ha[any_key] << anything
>
> Since the idiom is so common, what does everybody think of putting it into
> the standard library:
>
> def Hash.with_arrays
> new {|h,k| h[k] = []}
> end
>
> While we're at it, we might as well add
>
> def Hash.with_hashes
> new {|h,k| h[k] = Hash.new(&h.default_proc)}
> end
>
> Kind regards
>
> robert


Rather than making class methods on Hash to create special hashes like
this, why not make subclasses, so you can attach specialized instance
methods that make sense only for these kinds of hashes. For instance,
for the Hash-of-Hashes form, you might want a method that "rotates"
the Hash into a new Hash-of-Hashes like this:

def rotate
res = HashOfHashes.new
each { |ok, ov| ov.each { |ik, iv| res[ik][ok] = iv } }
res
end

 
Reply With Quote
 
 
 
 
Julian Leviston
Guest
Posts: n/a
 
      02-07-2009
Wow I like that. This is what I end up doing:

ha = {}
(ha[any_key] ||= []) << anything

J

On 07/02/2009, at 4:09 AM, Robert Klemme wrote:

>
> Hi there,
>
> we frequently do
>
> ha = Hash.new {|h,k| h[k] = []}
>
> so we can later do
>
> ha[any_key] << anything
>
> Since the idiom is so common, what does everybody think of putting
> it into the standard library:
>
> def Hash.with_arrays
> new {|h,k| h[k] = []}
> end
>
> While we're at it, we might as well add
>
> def Hash.with_hashes
> new {|h,k| h[k] = Hash.new(&h.default_proc)}
> end
>
> Kind regards
>
> robert
>



 
Reply With Quote
 
Simon Krahnke
Guest
Posts: n/a
 
      02-07-2009
* Robert Klemme <(E-Mail Removed)> (18:05) schrieb:

> ha = Hash.new {|h,k| h[k] = []}


> Since the idiom is so common, what does everybody think of putting it
> into the standard library:


Why not

def Hash.with(default=nil)
new { | h, k | h[k] = default.dup }
end

> While we're at it, we might as well add
>
> def Hash.with_hashes
> new {|h,k| h[k] = Hash.new(&h.default_proc)}
> end


I'm too tired for that. Does that create Hash with a default proc that
is the same as the one you specify right there?

mfg, simon .... l
 
Reply With Quote
 
Tom Link
Guest
Posts: n/a
 
      02-07-2009
> def Hash.with(default=3Dnil)
> =A0 new { | h, k | h[k] =3D default.dup }
> end


Not so good:

> h =3D Hash.with(0)
> h[1]

TypeError: can't dup Fixnum

I personally would appreciate a special constructor for Arrays.

 
Reply With Quote
 
Jesús Gabriel y Galán
Guest
Posts: n/a
 
      02-07-2009
On Sat, Feb 7, 2009 at 5:34 AM, Simon Krahnke <(E-Mail Removed)> wrote:
> * Robert Klemme <(E-Mail Removed)> (18:05) schrieb:


>> def Hash.with_hashes
>> new {|h,k| h[k] = Hash.new(&h.default_proc)}
>> end

>
> I'm too tired for that. Does that create Hash with a default proc that
> is the same as the one you specify right there?


Yes, it achieves having infinitely nested hashes:

irb(main):001:0> def Hash.with_hashes
irb(main):002:1> new {|h,k| h[k] = Hash.new(&h.default_proc)}
irb(main):003:1> end
=> nil
irb(main):004:0> h = Hash.with_hashes
=> {}
irb(main):005:0> h[1][2][3] = true
=> true
irb(main):006:0> h
=> {1=>{2=>{3=>true}}}

I agree that it would be nice to have them in the standard library,
but maybe Hash.of_hashes and Hash.of_arrays would be better names?

Jesus.

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      02-07-2009
On 07.02.2009 11:09, Jesús Gabriel y Galán wrote:
> On Sat, Feb 7, 2009 at 5:34 AM, Simon Krahnke <(E-Mail Removed)> wrote:


> I agree that it would be nice to have them in the standard library,
> but maybe Hash.of_hashes and Hash.of_arrays would be better names?


Yes, probably. I'm not religious about the names. My point was simply
that this is so often used that we might want to have it in the standard
library.

Cheers

robert

 
Reply With Quote
 
Trans
Guest
Posts: n/a
 
      02-07-2009


On Feb 6, 12:09=A0pm, Robert Klemme <(E-Mail Removed)> wrote:
> Hi there,
>
> we frequently do
>
> ha =3D Hash.new {|h,k| h[k] =3D []}
>
> so we can later do
>
> ha[any_key] << anything
>
> Since the idiom is so common, what does everybody think of putting it
> into the standard library:
>
> def Hash.with_arrays
> =A0 =A0new {|h,k| h[k] =3D []}
> end
>
> While we're at it, we might as well add
>
> def Hash.with_hashes
> =A0 =A0new {|h,k| h[k] =3D Hash.new(&h.default_proc)}
> end


I've been using the name #autonew for this last one.

Also @Tom Link

def Hash.with(default=3Dnil)
begin
new { | h, k | h[k] =3D default.dup }
rescue TypeError
new(default) # same as { | h, k | h[k] =3D default }
end
end

T.

 
Reply With Quote
 
Tom Link
Guest
Posts: n/a
 
      02-07-2009
> =A0 def Hash.with(default=3Dnil)
> =A0 =A0 begin


I think we have to insert a check for "dupability" here:

default.dup
> =A0 =A0 =A0 new { | h, k | h[k] =3D default.dup }

...

This method isn't capable of emulating the with_hashes method proposed
by Robert K though, is it?

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      02-07-2009
On 07.02.2009 11:26, Trans wrote:
>
> On Feb 6, 12:09 pm, Robert Klemme <(E-Mail Removed)> wrote:
>> Hi there,
>>
>> we frequently do
>>
>> ha = Hash.new {|h,k| h[k] = []}
>>
>> so we can later do
>>
>> ha[any_key] << anything
>>
>> Since the idiom is so common, what does everybody think of putting it
>> into the standard library:
>>
>> def Hash.with_arrays
>> new {|h,k| h[k] = []}
>> end
>>
>> While we're at it, we might as well add
>>
>> def Hash.with_hashes
>> new {|h,k| h[k] = Hash.new(&h.default_proc)}
>> end

>
> I've been using the name #autonew for this last one.
>
> Also @Tom Link
>
> def Hash.with(default=nil)
> begin
> new { | h, k | h[k] = default.dup }
> rescue TypeError
> new(default) # same as { | h, k | h[k] = default }
> end
> end


Where's the point of the rescue clause? The error will show up much
later, i.e. after the method has returned.

Also, as Tom pointed out, this is not the same as what I proposed - not
even similar.

Regards

robert
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Is the possible to have all the public constructors of the publicbase class as the constructors of a derived class? Peng Yu C++ 5 09-19-2008 10:19 AM
compiler synthesized constructors/copy constructors/assignment operators Jess C++ 5 06-07-2007 11:09 AM
Copy constructors, de/constructors and reference counts Jeremy Smith C++ 2 08-02-2006 11:25 PM
Constructors that call other Constructors Dave Rudolf C++ 12 02-06-2004 03:26 PM



Advertisments