String instance variable issue
Reported by Charles L | November 9th, 2007 @ 10:54 PM | in 1.0
Basically instance variables are popping up where they shouldn't:
% cat test.rb
p a = 'asdf'
p b = 'asdf'
p c = 'qwerty'
p a.object_id
p b.object_id
p c.object_id
p b.instance_variable_get(:@x)
p a.instance_variable_set(:@x, 1)
p b.instance_variable_get(:@x)
p c.instance_variable_get(:@x)
contrast the second last line here:
% ruby test.rb
"asdf"
"asdf"
"qwerty"
-605836498
-605836518
-605836538
nil
1
nil
nil
with here:
"asdf"
"asdf"
"qwerty"
262165
262173
262181
nil
1
1
nil
So "b" has picked up "a"'s instance variable, though they are different objects. Thought it was some sort of shared literal optimization, but doesn't look to be the case
Assembly:
#line 1
push_literal 0
string_dup
set a:0
pop
push_literal 1
string_dup
set b:1
pop
push_literal 2
string_dup
set c:2
...
Comments and changes to this ticket
-
Eero Saynatkari November 11th, 2007 @ 01:36 AM
- → Milestone changed from 1.0 preview to 1.0
- → State changed from new to open
Strings are implemented Copy-on-Write and it might be that it only detects modifications to the string itself, not the String object.
-
Eero Saynatkari November 11th, 2007 @ 01:37 AM
Erm, ignore everything after "Strings are implemented COW".. THAT might still have something to do with this, though. This is only Strings you have noticed the behaviour in?
-

Charles L November 11th, 2007 @ 05:49 AM
Yeah I wondered if it affects other objects, but it only seems to be strings so far. Eg, if you run this, the first 2 printed values will be 1:
'asdf'.instance_variable_set(:@x, 1) p 'asdf'.instance_variable_get(:@x) class MyString < String end MyString.new('asdf').instance_variable_set(:@x, 1) p MyString.new('asdf').instance_variable_get(:@x) [].instance_variable_set(:@x, 1) p [].instance_variable_get(:@x) {}.instance_variable_set(:@x, 1) p({}.instance_variable_get(:@x)) Object.new.instance_variable_set(:@x, 1) p(Object.new.instance_variable_get(:@x))Seems odd as you get different object ids, and i'd have thought the instance variables would be in the same struct that the object id refers to.
-

Charles L November 11th, 2007 @ 06:10 AM
Looking into it a bit further - I think its to do with the way that external instance variables are handled. It looks as if "object_get_ivars" looks up the object in a hash in order to find its associated instance variables.
Note that it doesn't affect [] though. In my tests, both "asdf" strings got the same hash from "object_hash_int", however, eg empty arrays (which also need external instance variables) get a different hash.
Is there any reason why this can't use object_id to lookup instead?
-
Eero Saynatkari January 8th, 2008 @ 11:07 PM
- → State changed from open to resolved
Looks like this has been fixed at some point. Closed.
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
