From: Stefano Crocco Date: 2012-10-24T00:52:45+09:00 Subject: Re: Name/symbol/object type clash? What is happening here? On Wednesday 24 October 2012 Todd Benson wrote > It's nonsense code, but I'm curious as to what is going on behind the > scenes... > > irb(main):001:0> S = Struct.new(:num) > => S > irb(main):002:0> class S; def change_to n; @num = n; end; end > => nil > irb(main):003:0> s = S.new(3) > # > irb(main):004:0> s.num = 4 > => 4 > irb(main):005:0> s.num > => 4 > irb(main):006:0> s.change_to(5) > => 5 > irb(main):007:0> s.num > => 4 > irb(main):008:0> s.instance_variables > => [:@num] > irb(main):009:0> s.instance_variable_set(:@num, 5) > => 5 > irb(main):010:0> s.num > => 4 > > Same thing happens if I don't define class S, but just define a method > on the instance... def s.change_to n; @num = n; end Apparently, classes created using Struct don't store values in instance variables (you can see this by calling #instance_variables on s immediately after creating it: it returns an empty array); rather they are stored internally in C-level variables which can't be accessed from ruby. Because of this, setting the @num instance variable doesn't have any effect on the value returned by #num. If you know C, you can see how Struct works internally looking at the file struct.c in the ruby source code. I hope this helps Stefano