From: Ryan Davis Date: 2009-08-01T05:15:38+09:00 Subject: Re: Modifying Struct members On Jul 31, 2009, at 09:50 , Yossef Mendelssohn wrote: > Is it possible to modify the members of a Struct class once it's been > created, yet retain all other behavior? > > An example: > > Thing = Struct.new(:a, :b, :c) do > def some_method > end > end > > Is there a way to modify Thing so it behaves as if it were effectively > created like so? > > Thing = Struct.new(:a, :b, :c, :d) do > def some_method > end > end I know this makes me a really bad person for doing this... but hey... that's what I'm here for. To take one for the team. I'm thinking of releasing 2 gems off of this idea. One for thaw and the other for struct... Hrm... there is still a problem with structs made before the additional member is added. I'll work that out, but I have to go to my workout now. #!/usr/bin/ruby -w require 'rubygems' require 'inline' class Object inline :C do |builder| builder.c "VALUE thaw() { FL_UNSET(self, FL_FREEZE); return self; }" end end class Struct inline :C do |builder| builder.c_singleton " void raw_members() { return rb_struct_s_members(self); } " builder.c_singleton ' void set_size(long n) { rb_iv_set(self, "__size__", LONG2NUM(n)); } ', :method_name => :size= end def self.add_member name self.raw_members.thaw self.raw_members << name attr_accessor name self.size = self.raw_members.size end end Thing = Struct.new(:a, :b, :c) do def some_thing end end t = Thing.new(1, 2, 3) p [t.a, t.b, t.c] # => [1, 2, 3] Thing.add_member :d t.d = 4 p [t.a, t.b, t.c, t.d] # => [1, 2, 3, 4]