# Newbie, hash or 2dArry

**URL:** <https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657>\
**Category:** Ruby\
**Created:** [March 30, 2007, 6:54pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657 "2007-03-30T18:54:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [March 30, 2007, 6:54pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/1 "2007-03-30T18:54:45Z")

</div>

I’m lost or just tired from guessing.

I need to make an hash I can call by hostname as the key and some random  
amount of data after that as the values. now a hash works great for 1  
to 1 maps (h[serverX] ==\> result) but I need  
h[serverX][query|result|time]

so how would I write a hash that would give me access to

in:  
h[host\_to\_query][“query”]] = @query  
h[host\_to\_query][“result”]] = queryhost(host\_to\_query,@query)

out:  
for h.each |host| puts h[[host][“result”]]

thanks

zaq

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [March 30, 2007, 7:06pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/2 "2007-03-30T19:06:25Z")

</div>

Alle venerdÃ¬ 30 marzo 2007, Zac E. ha scritto:

> h[host\_to\_query][“query”]] = @query  
> h[host\_to\_query][“result”]] = queryhost(host\_to\_query,@query)
> 
> out:  
> for h.each |host| puts h[[host][“result”]]
> 
> thanks
> 
> zaq

If I understand correctly, you can create a class with the required  
instances  
variables (or use Struct or OpenStruct) and store query and result  
there. For  
instance, using OpenStruct:

require ‘ostruct’

h[host\_to\_query] =OpenStruct.new(:query=\> @query, :result=  
queryhost(host\_to\_query,@query)

then

h.each\_value{|v| puts v.result}

For more information, you can look at the ri documentation for Hash,  
Struct  
and OpenStruct (ri Hash, ri Struct, ri OpenStruct).

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [March 30, 2007, 7:16pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/3 "2007-03-30T19:16:29Z")

</div>

Zac E. wrote:

> h[host\_to\_query][“query”]] = @query  
> h[host\_to\_query][“result”]] = queryhost(host\_to\_query,@query)
> 
> out:  
> for h.each |host| puts h[[host][“result”]]
> 
> thanks
> 
> zaq

Hey Zac,

Would a nested hash do the trick?

hash = { :host1 =\> {  
:query =\> @query,  
:result =\> queryhost(…),  
:time =\> time} }

then for output, you’d do something like  
for hash.each\_value do |value| puts value[:result] end

Hopefully that does the trick,  
Keith

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [March 30, 2007, 11:00pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/4 "2007-03-30T23:00:57Z")

</div>

On 30.03.2007 18:54, Zac E. wrote:

> h[host\_to\_query][“query”]] = @query  
> h[host\_to\_query][“result”]] = queryhost(host\_to\_query,@query)

This is syntactically incorrect since oyu have one closing bracket too  
much.

> out:  
> for h.each |host| puts h[[host][“result”]]

Here’s an alternative:

Info = Struct.new :query, :result, :time  
h = Hash.new {|h,k| h[k] = Info.new}  
h[serverX].query = @query  
h[serverX].result = queryhost(host\_to\_query,@query)  
h.each {|ho,inf| puts inf.result}

Of course you can use Arrays instead of Info but the code with Info is  
more readable and less error prone.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [April 5, 2007, 9:27pm UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/5 "2007-04-05T21:27:45Z")

</div>

first, thanks for the responses, ruby really is a great language.

My delima is that I’m trying to multithread the actions and store the  
results in a hash with the hostname as key

to redefine the issue, for each host I need a thread and I expect a  
result, then I’d like to be able to see the result in a  
hash[host][result]

but I’m having trouble mixing the hash with the thread. maybe I’m going  
about this all wrong. (this is outputting to a rails view, which is why  
i have “@vars”

I have

```
@threads = []
@resulthash = Hash.new(0)
@hostarray.each do |host|
    threads << Thread.new(host) do |myhost|
    @resulthash = { :myhost => {
    :packages => @mypackages,
    :result => doXMLquery(host,@mypackages)} }
    logger.info("host = " + host + ", result = " + 

```

@resulthash[:myhost][:result])  
end  
end

@threads.each {|thr| thr.join }

logger.info(“result of threads…”)  
@hostarray.each do |myhost|  
logger.info("host = " + myhost + ", result = " +  
@resulthash[:myhost][:result])  
end

logger output

host = hostX, result = --data returned from hostX–  
host = hostY, result = --data returned from hostY–  
result of threads…  
host = hostX, result = --data returned from hostY–  
host = hostY, result = --data returned from hostY–

I’m clearly loosing context of the [:host][:result] in the final two  
lines.

any pointers?

thanks  
-zaq

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [April 6, 2007, 12:14am UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/6 "2007-04-06T00:14:39Z")

</div>

I used Openstruct and it appears to give me what I want. I’m still  
interested in why a nested hash didn’t work if anyone knows.

thanks again  
-zaq

---

<div class="post-metadata">

**Author:** ![zaq](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/f04885/32.png) [@zaq](https://www.ruby-forum.com/u/zaq)\
**Post date:** [April 6, 2007, 5:21am UTC](https://www.ruby-forum.com/t/newbie-hash-or-2darry/90657/7 "2007-04-06T05:21:18Z")

</div>

I admit I didn’t fully read the whole script, but I saw something that  
looks wrong. A simple syntax mistake? See further down.

Zac E. wrote:

> about this all wrong. (this is outputting to a rails view, which is why  
> i have “@vars”
> 
> I have
> 
> ```
> @threads = []
> @resulthash = Hash.new(0)
> @hostarray.each do |host|
> threads << Thread.new(host) do |myhost|
> 
> ```

Here, you are resetting @resulthash. Maybe you meant:  
@resulthash[myhost] = {:packages =\> @mypackages,  
:result =\> doXMLquery(host,@mypackages)}
