Forum: Ruby Hash default -- what's going on here?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D842c2f60cc988204e31d85a01db4bcc?d=identicon&s=25 unknown (Guest)
on 2006-03-15 08:10
(Received via mailing list)
I've hit what is either an egregious bug in ruby (1.8.4) or some
subtlety
that I haven't grasped.  [Most likely the latter... (:-)]

Briefly I had two arrays of symbol strings of which I wanted to find
which symbols occurred in both arrays, so I thought I'd use a hash with
the key being the symbol and the value a two element array that would
be used to flag which set(s) the symbol was found in.  The following
is a simplified (and 'instrumented') version of what I was trying to
do:

listA=["line1","line2","line3"]
listB=["line5","line3","line4"]
table={}
table.default=[0,0]
print "table default originally: ", table.default, "\n"

listA.each {|a| t=table[a]; print a," -- undef value: ",t;
			t[0]=1; print "  new value: ",t,"\n";
			table[a]=t}
print "table default now: ", table.default, "\n"

listB.each {|a| t=table[a]; print a," -- undef value: ",t;
			t[1]=1; print "  new value: ",t,"\n";
			table[a]=t}

print "table default now: ", table.default, "\ntable contents:\n"
table.each {|k,v| print k, ": ", v[0], v[1], "\n"}


Now, in the 'each' statements, the variable 'a' should (except in one
case)
not be in the hash yet, so I would expect the original provided default
to
be returned.  However, here's the printout I get:

table default now: 00
line1 -- undef value: 00  new value: 10
line2 -- undef value: 10  new value: 10
line3 -- undef value: 10  new value: 10
table default now: 10
line5 -- undef value: 10  new value: 11
line3 -- undef value: 11  new value: 11
line4 -- undef value: 11  new value: 11
table default now: 11
table contents:
line1: 11
line2: 11
line3: 11
line4: 11
line5: 11


Dunhh?  Why is the default value getting changed?  I can't see that
I'm resetting it anywhere.  If I do the same sort of manipulations
outside of a block (one at a time in irb for instance) things happen
as I would expect -- the default remains as set, and is returned for
any undefined key.

Illumination appreciated.
				-- Pete --
Bd0203dc8478deb969d72f52e741bd4f?d=identicon&s=25 Daniel Baird (Guest)
on 2006-03-15 08:19
(Received via mailing list)
I'm guessing it's got something to do with your assignment

                        table[a]=t

the array that is the hash's default can be assigned to.  I think that's
what you're doing.  If i did some testing I might be more sure :)

;Daniel

On 15/03/06, Pete Goodeve <pete@jwgibbs.cchem.berkeley.edu> wrote:
> do:
> print "table default now: ", table.default, "\n"
> case)
> line4 -- undef value: 11  new value: 11
> I'm resetting it anywhere.  If I do the same sort of manipulations
> outside of a block (one at a time in irb for instance) things happen
> as I would expect -- the default remains as set, and is returned for
> any undefined key.
>
> Illumination appreciated.
>                                 -- Pete --
>
>
>


--
Daniel Baird
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog ::
Things
That Suck)
[[My webhost uptime is ~ 92%.. if no answer pls call again later!]]
5a601582df3b42b65a5e8353fc9305da?d=identicon&s=25 Gerardo Santana Gómez Garrido (Guest)
on 2006-03-15 08:41
(Received via mailing list)
2006/3/15, Pete Goodeve <pete@jwgibbs.cchem.berkeley.edu>:
>
> listA=["line1","line2","line3"]
> listB=["line5","line3","line4"]
> table={}

Here's the problem:

> table.default=[0,0]


What you are looking for is:

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

otherwise you are always pointing to _the same_ object
D842c2f60cc988204e31d85a01db4bcc?d=identicon&s=25 unknown (Guest)
on 2006-03-15 10:09
(Received via mailing list)
In article <ca19f32e0603142317y1b97a5c9k@mail.gmail.com>,
Daniel Baird <danielbaird@gmail.com> wrote:
>what you're doing.  If i did some testing I might be more sure :)
>

Heh -- you can tell I'm new to ruby... (:-))

An hour after I posted I suddenly realized what is going on.
When you assign an array, the array is *not* copied!  the assigned-to
variable just gets a pointer to the other array.

So when I did "t=table[a]" I was setting t to a pointer to the default!
When I changed t[n], of course the default was actually what got
changed...

Sigh.  Hardly a novel gotcha, but I fell right into it.

Not sure of the best way to do what I want -- maybe just use 'has_key?'
and then do the right thing.
					-- Pete --
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-03-15 15:29
(Received via mailing list)
"Pete Goodeve" <pete@jwgibbs.cchem.berkeley.edu> wrote in message
news:dv8lhf$18m$1@jwgibbs.CChem.Berkeley.EDU...
> Not sure of the best way to do what I want -- maybe just use 'has_key?'
> and then do the right thing.

The question is what exactly are you trying to do?

    robert
This topic is locked and can not be replied to.