logo       

Re: Modifying Struct members: msg#02421

ruby-talk

Subject: Re: Modifying Struct members

here we go:

#!/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_s_size(long n) {
rb_iv_set(self, "__size__", LONG2NUM(n));
}
', :method_name => :size=

builder.c '
void set_size(long n) {
RSTRUCT(self)->len = n;
}
', :method_name => :size=
end

def self.add_member name
self.raw_members.thaw
self.raw_members << name

# a bit hacky, but works
self.send(:define_method, name) { self[name] }
self.send(:define_method, "#{name}=") { |o| self[name] = o }

new_size = self.raw_members.size
self.size = new_size

ObjectSpace.each_object(self) do |o|
o.size = new_size
end
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 # t['d'] = 4 works just as well now

p(('a'..'d').map { |c| t[c] })
# => [1, 2, 3, 4]
p(('a'..'d').map { |c| t.send c })
# => [1, 2, 3, 4]



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | Mail Home | sitemap | FAQ | advertise