Newbie question:Does Ruby have the structure of hash's array like Perl does?

Something like below doesn’t work:
h=Hash.new
h[“a”][0]="something"
h[“a”][1]=“another thing”

and what’s the equivalence of Perl’s $"?

thx,

Lei Weng

Something like below doesn’t work:
h=Hash.new
h[“a”][0]=“something”
h[“a”][1]=“another thing”

h=Hash.new
h[“a”] = Array.new
h[“a”][0]=“something”
h[“a”][1]=“another thing”

Ruby doesn’t quite have Perl’s “implicit declaration”.

and what’s the equivalence of Perl’s $"?

What does Perl’s $" have?

···


Daniel Carrera
Graduate Teaching Assistant. Math Dept.
University of Maryland. (301) 405-5137

depone: depone (di-POHN) verb tr., intr.
To declare under oath.

Try this (I just did in irb):

h = Hash.new
h[“a”] = Array.new
h[“a”][0] = “something”

Then h[“a”] returns:

[“something”]

Defining h[“a”] as an empty array is what you seemed to be missing.

BTW, h[“a”] = will of course work just as well.

HTH

···

On Fri, 28 Mar 2003 16:01:04 +0900, Weng Lei-QCH1840 wrote:

Something like below doesn’t work:
h=Hash.new
h[“a”][0]=“something”
h[“a”][1]=“another thing”

and what’s the equivalence of Perl’s $"?

thx,

Lei Weng


Tim Kynerd Sundbyberg (småstan i storstan), Sweden tkynerd@spamcop.net
Sunrise in Stockholm today: 5:31
Sunset in Stockholm today: 18:15
My rail transit photos at http://www.kynerd.nu

“Tim Kynerd” tkynerd@spamcop.net schrieb im Newsbeitrag
news:pan.2003.03.28.07.17.11.199188@spamcop.net

Something like below doesn’t work:
h=Hash.new
h[“a”][0]=“something”
h[“a”][1]=“another thing”

h = Hash.new
h[“a”] = Array.new
h[“a”][0] = “something”

I think in older versions you can achieve this by
(h[“a”] ||= )[0] = “something”

I think newer versions can do

h = Hash.new{Array.new}
h[“a”][0] = “something”

Regards

robert
···

On Fri, 28 Mar 2003 16:01:04 +0900, Weng Lei-QCH1840 wrote:

The first works:
vor-lord:i686/debug> irb
irb(main):001:0> h = Hash.new
=> {}
irb(main):002:0> (h[“a”] ||= )[0] = “something”
=> “something”
irb(main):003:0> h[“a”]
=> [“something”]
irb(main):004:0> h[“a”][0]
=> “something”

I’m not sure this is as clear as I’d like, I’d probably choose to do something
easier to read but more verbose:

h[“a”] = Array.new unless h.include?(“a”)
h[“a”][0] = “something”

But your second example doesn’t work with CVS Ruby from two days ago:

vor-lord:i686/debug> irb
irb(main):001:0> RUBY_VERSION
=> “1.8.0”
irb(main):002:0> h = Hash.new{Array.new}
=> {}
irb(main):003:0> h[“a”][0] = “something”
=> “something”
irb(main):004:0> h[“a”]
=>
irb(main):005:0> h[“a”][0]
=> nil

I understand Hash.new(Array.new) even though I was caught trying to do the
following once (ok, twice :wink: upon a time:

irb(main):001:0> h = Hash.new(Array.new)
=> {}
irb(main):002:0> h[“a”][0] = “something”
=> “something”
irb(main):003:0> h[“a”]
=> [“something”]
irb(main):004:0> h[“a”][0]
=> “something”
irb(main):005:0> h[“b”][0] = “something_else”
=> “something_else”
irb(main):006:0> h[“a”]
=> [“something_else”]

OOPS! The same object is returned as the default value.

It looks like the block form gives you a new object each time to return when a
key doesn’t exist in the hash, but it doesn’t assign that as the value of the
key. Is that correct?:

irb(main):001:0> h = Hash.new{Array.new}
=> {}
irb(main):002:0> h[“a”][0] = “something”
=> “something”
irb(main):003:0> h.keys
=>

{Array.new} gives:
irb(main):001:0> h = Hash.new{Array.new}
=> {}
irb(main):002:0> h[“foo”].id
=> 537955172
irb(main):003:0> h[“bar”].id
=> 537950392
irb(main):004:0> h[“foo”].id
=> 537945462

whereas (Array.new) gives:
irb(main):001:0> h = Hash.new(Array.new)
=> {}
irb(main):002:0> h[“foo”].id
=> 537959972
irb(main):003:0> h[“bar”].id
=> 537959972

So the block form gives you a unique object for each call to a non-existent
key, but still doesn’t implicitly assign anything to that key. So in your
second example the Array.new is created and has [0] assigned, but there are no
references to it so it will just be garbage collected.

Thanks for the tip though, I wasn’t aware of the block form, that is a cool new
feature that I can make use of!

···

On Mar 28, Robert Klemme wrote:

I think in older versions you can achieve this by
(h[“a”] ||= )[0] = “something”

I think newer versions can do

h = Hash.new{Array.new}
h[“a”][0] = “something”

Regards

robert

irb(main):002:0> h = Hash.new{Array.new}

Try this (with 1.8)

   h = Hash.new { |hash, key| hash[key] = }

Guy Decoux

Hi –

It looks like the block form gives you a new object each time to
return when a key doesn’t exist in the hash, but it doesn’t assign
that as the value of the key. Is that correct?:

Yes; the default value for a hash is what you get for non-existent
keys, with no assignment implied, and the block form is just an
recent extension of that behavior.

It does lead to some interesting constructs:

h = Hash.new { }
h[1] = h[1] # not a sight you see often!
h[2].id == h[2].id # false

and one of my favorites:

h = Hash.new { raise “Access denied!” }

:slight_smile:

David

···

On Fri, 28 Mar 2003, Brett H. Williams wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav