T
trans. (T. Onoma)
How 'bout an OpenStruct#update for adding values after initialization. Or is
there another way to do?
Thanks,
T.
there another way to do?
Thanks,
T.
How 'bout an OpenStruct#update for adding values after initialization. Or is
there another way to do?
Hi David,
| > How 'bout an OpenStruct#update for adding values after initialization. Or
| > is there another way to do?
|
| OpenStruct needs to be very conservative about what methods it has,
| since the whole point of it is to allow you to make up arbitrarily
| named members.
Why so conservative? So they don't overwrite standard object methods? I
wondered why accessors weren't used. I suppose a hash is faster too. Hek,
maybe '@' itself should be hash and forget about it
| But I'm also not sure what you need to do that you can't do. The
| OpenStruct object should let you add values indefinitely.
This is what I mean:
o = OpenStruct.new( foo_hash )
# later ...
o.update( bar_hash )
The reason is because I am modifying and using the object on the fly.
Hi,
In message "Re: OpenStruct#update ?"
|I'm assuming so. Actually here's what happens if you try:
|
| irb(main):020:0> o = OpenStruct.new
| => <OpenStruct>
| irb(main):021:0> o.class = 1
| => 1
| irb(main):022:0> o.class
| => OpenStruct
I'm thinking of making OpenStruct raise error for assignment to
existing method. I'm not sure whether I should prohibit private
method overriding, i.e. cases Hal pointed out in [ruby-talk:117889].
trans. (T. Onoma) said:Sure. Okay first, basically what I was doing, given object o and data in hash
h:
h.each do |k,v|
o.instance_variable_set("@#{k}", v)
o.instance_eval <<-EOS
def #{k}; @#{k}; end
def #{k}=(x); @#{k}=x; end
EOS
end
Florian Gross said:h.each do |k,v|
class << o; self; end.sendattr_accessor, k)
o.k = v
end
h.each do |k,v|
class << o; self; end.sendattr_accessor, k)
o.k = v
end
Maybe .meta_class and .meta_class_eval should really be part of Standard
Ruby...
Robert said:Are you sure, this works? IMHO this is more efficient:
class << o; self; end.sendattr_accessor, *h.keys)
h.each do |k,v|
o.send("#{k}=", v)
end
But it would be even better to check for existing methods in order to not
overwrite existing methods:
cl = class << o; self; end
im = cl.instance_methods
h.each do |k,v|
cl.sendattr_reader, k) unless im.include?(k.to_s)
cl.sendattr_writer, k) unless im.include?("#{k}=")
o.send("#{k}=", v)
end
David said:I've got an RCR in for singleton_class. (I know, the terminology is
different, but it's the same idea I still don't know what the
perfect word would be for That Class.) I don't think a separate
_class_eval method would be necessary or good. As with every other
class, you could just call class_eval on the class object.
I firmly believe that having a singleton_class method (or whatever
it's called) would make it much, much easier for people to understand
the whole design. See <http://www.rcrchive.net/rcr/show/231>.
Hm, looks like I already voted on it. I can live with it being named
#singleton_class, #meta_class or even #virtual_class -- I don't really
know what name would be best. I'm just in favor of #meta_class because
it avoids the name clash with the singleton pattern. (Which seems to be
obsolete in Ruby anyway -- it seems to be the case that everywhere where
you would use it you can just as well use a Module...)
I guess it's probably best to let matz decide the name.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.