Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > being very confused about this hash

Reply
Thread Tools

being very confused about this hash

 
 
Ruby Newbee
Guest
Posts: n/a
 
      01-06-2010
Hi,

irb(main):039:0> hash = Hash.new []
=> {}
irb(main):040:0> hash['abc'] << 3
=> [3]
irb(main):041:0> hash.keys
=> []
irb(main):042:0> hash['def']
=> [3]


Since I have created a key/value pair with hash['abc'] << 3, why
hash.keys show nothing?
And, why hash['abc'] << 3 changed the hash's default value (which
should be an empty array)?

Thanks.

 
Reply With Quote
 
 
 
 
Bill Kelly
Guest
Posts: n/a
 
      01-06-2010
Ruby Newbee wrote:
>
> irb(main):039:0> hash = Hash.new []
> => {}
> irb(main):040:0> hash['abc'] << 3
> => [3]
> irb(main):041:0> hash.keys
> => []
> irb(main):042:0> hash['def']
> => [3]
>
>
> Since I have created a key/value pair with hash['abc'] << 3, why
> hash.keys show nothing?
> And, why hash['abc'] << 3 changed the hash's default value (which
> should be an empty array)?


I'm not sure why hash.keys was empty.

But with regard to the default value, we are providing an
object (a specific instance of the Array class) to be used
as the default.

We can illustrate this by asking Ruby to show us the object_id
of the default object:

irb(main):001:0> ary = []
=> []
irb(main):002:0> ary.object_id
=> 20919800
irb(main):003:0> h = Hash.new ary
=> {}
irb(main):004:0> h['foo'].object_id
=> 20919800
irb(main):005:0> h['bar'].object_id
=> 20919800

So we can see the object_id of the default object is indeed
the same object_id of the array we provided to Hash.new.

* * *

We can instead provide a block to Hash.new which allows us
to create a _new_ unique object (instance of Array) whenever
a new default value is needed:

irb(main):001:0> h = Hash.new {|h,k| h[k] = []}
=> {}
irb(main):002:0> h['abc'] << 3
=> [3]
irb(main):003:0> h.keys
=> ["abc"]
irb(main):004:0> h['def']
=> []


Regards,

Bill



 
Reply With Quote
 
 
 
 
David Masover
Guest
Posts: n/a
 
      01-06-2010
On Tuesday 05 January 2010 09:39:53 pm Ruby Newbee wrote:
> irb(main):039:0> hash = Hash.new []


I assume here that [] is the default value, right?
> => {}
> irb(main):040:0> hash['abc'] << 3
> => [3]
> irb(main):041:0> hash.keys
> => []
> irb(main):042:0> hash['def']
> => [3]
>
>
> Since I have created a key/value pair with hash['abc'] << 3, why
> hash.keys show nothing?


Because you haven't set anything in the hash. That is,

hash['abc'] = 3

is equivalent to:

hash.[]=('abc', 3)

On the other hand, what you've done is:

hash['abc'] << 3

That's equivalent to:

hash.[]('abc') << 3

I don't know if that helps, but that's the difference. Let me put it this way
-- suppose you hadn't changed the default value:

irb(main):001:0> hash = {}
=> {}
irb(main):002:0> hash['abc']
=> nil
irb(main):003:0> hash.keys
=> []

Do you understand why that works the way it does? But there's nothing special
about nil here, it's just the, erm, _default_ default value -- it's what Hash
uses as a default value if you don't specify one.

> And, why hash['abc'] << 3 changed the hash's default value (which
> should be an empty array)?


Because you set the default value to [], which creates an empty array object,
once. The hash is just assigning it each time. Think of it this way:

irb(main):004:0> default = []
=> []
irb(main):005:0> a = default
=> []
irb(main):006:0> b = default
=> []
irb(main):007:0> a << 3
=> [3]
irb(main):008:0> b
=> [3]

What you really want is the block notation of creating a hash, which lets you
actually specify some code that's run to create a default value, as Bill Kelly
says. The reason his code works is that when you try to access a value that
doesn't exist, it actually runs some code which sets that value:

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

It wouldn't work at all if you just did this:

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

That would at least give you a new array each time, but since it wouldn't set
it, you'd see weird things:

irb(main):010:0> h['abc'] << 3
=> [3]
irb(main):011:0> h['abc']
=> []
irb(main):012:0> h.keys
=> []

 
Reply With Quote
 
Ruby Newbee
Guest
Posts: n/a
 
      01-06-2010
On Wed, Jan 6, 2010 at 1:52 PM, David Masover <> wrote:
> On Tuesday 05 January 2010 09:39:53 pm Ruby Newbee wrote:
>> Since I have created a key/value pair with hash['abc'] << 3, why
>> hash.keys show nothing?

>
> Because you haven't set anything in the hash. That is,
>
> hash['abc'] = 3
>
> is equivalent to:
>
> hash.[]=('abc', 3)
>
> On the other hand, what you've done is:
>
> hash['abc'] << 3
>
> That's equivalent to:
>
> hash.[]('abc') << 3
>



Thanks for the explaining, now I think I have got it.
I'm always thinking it as the Perl way, since in Perl the syntax like
hash['abc'] << 3 will create a key/value pairs.

perl -MData:umper -le '$hash={}; push @{$hash->{'abc'}},3; print Dumper $hash'
$VAR1 = {
'abc' => [
3
]
};


I didn't know in Ruby hash['abc'] = 3 and hash['abc'] << 3 are different.
Thanks again.

 
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
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
Quick Book file access very very very slow Thomas Reed Computer Support 7 04-09-2004 08:09 PM
Very new - Very confused Jim ASP .Net Datagrid Control 0 08-04-2003 02:05 PM
very Very VERY dumb Question About The new Set( ) 's Raymond Arthur St. Marie II of III Python 4 07-27-2003 12:09 AM



Advertisments