double assignation in a hash

N

nico Itkin

hi !

I'm new to ruby, i'd like to know if it is possible to make the
following kind of assignation in a hash, like i used to do in php :

a={}
a[:b][:c]="value"

the goal for me is to create a hash by iterating on keys, like

hash={}
[a,b,c].each do |k1|
[d,e,f].each do |k2|
hash[k1][k2] = afunction(k1,k2)
end
end

this last code lead to a nil.[] error

Could you help me ? .
 
R

Rob Biedenharn

hi !

I'm new to ruby, i'd like to know if it is possible to make the
following kind of assignation in a hash, like i used to do in php :

a={}
a[:b][:c]="value"

the goal for me is to create a hash by iterating on keys, like

hash={}
[a,b,c].each do |k1|
[d,e,f].each do |k2|
hash[k1][k2] = afunction(k1,k2)
end
end

this last code lead to a nil.[] error

Could you help me ? .


Your problem is that a[:b] is not a hash. You can get this effect by
defining a default for the hash 'a' like so:

irb> a = Hash.new {|h,k| h[k] = {} }
=> {}
irb> a[:b][:c] = 'value'
=> "value"
irb> a
=> {:b=>{:c=>"value"}}

The block supplied to Hash.new is called with the hash and the key
when the key doesn't exist. So the effect is as if you had:

a = {}
a[:b] = {}
a[:b][:c] = 'value'

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
G

Gregory Seidman

hi !

I'm new to ruby, i'd like to know if it is possible to make the
following kind of assignation in a hash, like i used to do in php :

a={}
a[:b][:c]="value"

the goal for me is to create a hash by iterating on keys, like

hash={}
[a,b,c].each do |k1|
[d,e,f].each do |k2|
hash[k1][k2] = afunction(k1,k2)
end
end

this last code lead to a nil.[] error

Could you help me ? .

You may find this of interest:

http://redcorundum.blogspot.com/2007/05/just-nifty-meta-meta-tidbit.html

--Greg
 
J

Jesús Gabriel y Galán

hi !

I'm new to ruby, i'd like to know if it is possible to make the
following kind of assignation in a hash, like i used to do in php :

a={}
a[:b][:c]="value"

For arbitrary hash nesting, try this:

irb(main):023:0> a = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
irb(main):024:0> a[1][2][3][4] = "hello"
irb(main):025:0> a
=> {1=>{2=>{3=>{4=>"hello"}}}}
irb(main):026:0> a[1][2][3][4]
=> "hello"


Hope this helps,

Jesus.
 
D

Dave Bass

Jesús Gabriel y Galán said:
For arbitrary hash nesting, try this:

irb(main):023:0> a = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
irb(main):024:0> a[1][2][3][4] = "hello"
irb(main):025:0> a
=> {1=>{2=>{3=>{4=>"hello"}}}}
irb(main):026:0> a[1][2][3][4]
=> "hello"

Or this (longer but clearer IMO):

a = {}
a[1] = {}
a[1][2] = {}
a[1][2][3] = {}
a[1][2][3][4] = "hello"

print a[1][2][3][4] # "hello"
 
N

nico Itkin

Thanks evebody for yours answers, helps a lot :) !

Jesús : looks fantastic, but could you give me fex explanation how it
works?
a = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}

is this a way to override the method new for the object a?

You're doing so by passing the following block but then i'm lost, do you
have any links to share which detail that ?

Nico (so much to learn...)
 
J

Jesús Gabriel y Galán

Thanks evebody for yours answers, helps a lot :) !

Jes=FAs : looks fantastic, but could you give me fex explanation how it
works?
a =3D Hash.new {|h,k| h[k] =3D Hash.new(&h.default_proc)}

is this a way to override the method new for the object a?

You're doing so by passing the following block but then i'm lost, do you
have any links to share which detail that ?

Hash.new receives a block, which is executed whenever you try to access
a non-existing key. In the block you can assign a value to the key in the h=
ash.
The value that we assign above is a hash. If we did this:

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

Then we would achieve a two-level hash, but the second level hash,
wouldn't be able to assign a next level hash to a non-existing key, because
a block wasn't provided.

Hash has a default_proc variable that contains the block (in proc form)
that was passed to the constructor, so if we assign this proc as the block
for the constructor, we get a hash that can assign a hash to a non-existing=
key,
in a recursive way, cause each hash will pass its default proc to the hash
created in the constructor block.

So many words that I don't know if I made myself clear...

Jesus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top