OpenStruct#update?

"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:2vrj8eF2oj365U1@uni-berlin.de...

> trans. (T. Onoma) wrote:
> > 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
>
> h.each do |k,v|
> class << o; self; end.send(:attr_accessor, k)
> o.k = v
> end

Are you sure, this works? IMHO this is more efficient:

Actually the example is pulled inside out from the real method I use which is
a method of class Object (where it does work). So no the above probably
doesn't work as give --but was just intended to give approx. notion of what
I'm doing.

class << o; self; end.send(:attr_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.send(:attr_reader, k) unless im.include?(k.to_s)
   cl.send(:attr_writer, k) unless im.include?("#{k}=")
   o.send("#{k}=", v)
end

I'm not sure I want that. Hmm... It's a sticky issue depending largely on the
particular use case. I think it makes sense for general use, so yes --I'll
add something like that, thanks. Should it raise an error instead?

But in the context of an OpenStruct, no. OpenStruct focus is on data.

T.

···

On Monday 15 November 2004 07:38 am, Robert Klemme wrote:

Off the top of my head, would this work?

  def marshal_dump
      Marshal.dump(@table)
  end

  def marshal_load(obj)
      @table = Marshal.load(obj)
      @table.each_key{|key| self.new_ostruct_member(key) }
  end

T.

···

On Wednesday 17 November 2004 07:56 am, trans. (T. Onoma) wrote:

On Wednesday 17 November 2004 07:04 am, Mauricio Fernández wrote:
> While you are at it, please consider
>
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3687
>
> and the other msgs in that thread.

Okay, thanks. So what constitutes compatible marshal data?

Hi --

···

On Mon, 15 Nov 2004, Florian Gross wrote:

David A. Black wrote:

>>Maybe .meta_class and .meta_class_eval should really be part of Standard
>>Ruby...
>
> I've got an RCR in for singleton_class. (I know, the terminology is
> different, but it's the same idea :slight_smile: 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&gt;\.

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.

Yeah, as long as he doesn't choose 'virtual' :slight_smile:

David

P.S. Yes, I know this is going to the list :slight_smile:

--
David A. Black
dblack@wobblini.net

"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:2vrofmF2ouoprU1@uni-berlin.de...

Robert Klemme wrote:

> "Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
>>h.each do |k,v|
>> class << o; self; end.send(:attr_accessor, k)
>> o.k = v
>>end
>
> Are you sure, this works? IMHO this is more efficient:
>
> class << o; self; end.send(:attr_accessor, *h.keys)
> h.each do |k,v|
> o.send("#{k}=", v)
> end

You are right of course. I also like how you moved the attr_accessor out
of the loop -- nice idea.

Thanks!

> 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.send(:attr_reader, k) unless im.include?(k.to_s)
> cl.send(:attr_writer, k) unless im.include?("#{k}=")
> o.send("#{k}=", v)
> end

Hm, I think that would still overwrite methods of o's class and
inherited ones.

I don't think so:

class Foo; attr_accessor :bar end

=> nil

f=Foo.new

=> #<Foo:0x10187ef0>

class <<f; instance_methods.include?("bar") end

=> true

The singleton class of f knows about instance methods defined in super
classes. Which is logical, considering this:

class <<f; ancestors end

=> [Foo, Object, Kernel]

What about this?

accessors = h.keys - o.methods
class << o; self; end.send(:attr_accessor, *accessors)
h.each do |key, value|
   o.send("#{key}=", value) if accessors.include?(key)
end

Nice and short. But it has some drawbacks:

(with f and Foo as above)

h={:foo=>"foo", :bar=>"bar"}

=> {:foo=>"foo", :bar=>"bar"}

h.keys-f.methods

=> [:foo, :bar]

h.keys

=> [:foo, :bar]

You would want ":bar" removed from the keys but it isn't because f.methods
returns an array of String. (I assume that symbols are the most likely
keys for the hash - which might be wrong.)

Plus, it's not selective enough IMHO because if you just have a setter,
then that is overwritten. And if you just have a getter, then no setter
is defined and you get an error during o.send("#{key}="...).

Kind regards

    robert

"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag
news:200411150844.12388.transami@runbox.com...

> "Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
> news:2vrj8eF2oj365U1@uni-berlin.de...
>
> > trans. (T. Onoma) wrote:
> > > 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
> >
> > h.each do |k,v|
> > class << o; self; end.send(:attr_accessor, k)
> > o.k = v
> > end
>
> Are you sure, this works? IMHO this is more efficient:

Actually the example is pulled inside out from the real method I use

which is

a method of class Object (where it does work). So no the above probably
doesn't work as give --but was just intended to give approx. notion of

what

I'm doing.

I mean't Florian's code not yours. Sorry if that hasn't become clear
'nough.

> class << o; self; end.send(:attr_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.send(:attr_reader, k) unless im.include?(k.to_s)
> cl.send(:attr_writer, k) unless im.include?("#{k}=")
> o.send("#{k}=", v)
> end

I'm not sure I want that. Hmm... It's a sticky issue depending largely

on the

particular use case. I think it makes sense for general use, so

yes --I'll

add something like that, thanks. Should it raise an error instead?

But in the context of an OpenStruct, no. OpenStruct focus is on data.

Full ACK.

Kind regards

    robert

···

On Monday 15 November 2004 07:38 am, Robert Klemme wrote:

It introduces an unneeded indirection level (you end up
marshalling a string with the marshalled table; compare to
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3690\) and
doesn't solve the data compatibility problem: I believe that the goal
is having

# run with the new code
File.open("data", "w"){|f| f.write Marshal.dump(OpenStruct.new(:a => 1))}

# run with the old code
p Marshal.load(File.read("data")) # we want => OpenStruct, not String or Hash

and vice versa.

···

On Wed, Nov 17, 2004 at 10:26:48PM +0900, trans. (T. Onoma) wrote:

> > While you are at it, please consider
> >
> > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3687
> >
> > and the other msgs in that thread.
>
> Okay, thanks. So what constitutes compatible marshal data?

Off the top of my head, would this work?

  def marshal_dump
      Marshal.dump(@table)
  end

  def marshal_load(obj)
      @table = Marshal.load(obj)
      @table.each_key{|key| self.new_ostruct_member(key) }
  end

--
Hassle-free packages for Ruby?
RPA is available from http://www.rubyarchive.org/

He he. Seems like all the readily floated possibilities have poor
connotations. I've heard complaints about all three: 'virtual', 'meta', and
of course, 'singleton'. So what do others think of 'instance' class? Or more
to the point 'special' class -- a specialton :wink:

T.

···

On Monday 15 November 2004 08:45 am, David A. Black wrote:

Yeah, as long as he doesn't choose 'virtual' :slight_smile:

Robert Klemme wrote:

The singleton class of f knows about instance methods defined in super
classes. Which is logical, considering this:

Ah, I was confusing instance_methods() with instance_methods(false).

accessors = h.keys - o.methods
class << o; self; end.send(:attr_accessor, *accessors)
h.each do |key, value|
  o.send("#{key}=", value) if accessors.include?(key)
end

Nice and short. But it has some drawbacks:
[...]

You would want ":bar" removed from the keys but it isn't because f.methods
returns an array of String. (I assume that symbols are the most likely
keys for the hash - which might be wrong.)

Hm, I assumed the hash would contain Strings as keys. I guess it could be normalized to that.

Plus, it's not selective enough IMHO because if you just have a setter,
then that is overwritten. And if you just have a getter, then no setter
is defined and you get an error during o.send("#{key}="...).

I was trying to work around methods in Kernel -- I don't think it makes sense to have o.p = when you don't have o.p. But I guess the check isn't strictly needed anyway. (attr_accessor :stuck_out_tongue: will create a public getter. I thought it would create a private one.)

Hi,

···

In message "Re: Kernel#singleton_class" on Mon, 15 Nov 2004 22:45:31 +0900, "David A. Black" <dblack@wobblini.net> writes:

I guess it's probably best to let matz decide the name.

Yeah, as long as he doesn't choose 'virtual' :slight_smile:

I'd call them singleton classes. Any objection?

              matz.

Hi --

>
> Yeah, as long as he doesn't choose 'virtual' :slight_smile:

He he. Seems like all the readily floated possibilities have poor
connotations. I've heard complaints about all three: 'virtual', 'meta', and
of course, 'singleton'. So what do others think of 'instance' class? Or more
to the point 'special' class -- a specialton :wink:

In thinking about such things my mind always jumps to the question:
how easy (or not) will it be to explain to people? I think instance
class might be fairly good in that regard, but I'm not sure it's
logical. Why not "object class", since above all everything that has
one is an object? Which also means it's an instance, but why choose
that as its main identity? (Not that I like "object class"; I'm just
not sure that I'm seeing the reasoning behind "instance class".)

I'd also thought of "own class", as in:

  obj.class
  obj.own_class

(I'd actually prefer #class to be deprecated in favor of #birth_class,
so as to make a clearer pairing of, and distinction between, an
object's two classes. but I do not expect that to happen :slight_smile:

David

···

On Mon, 15 Nov 2004, trans. (T. Onoma) wrote:

On Monday 15 November 2004 08:45 am, David A. Black wrote:

--
David A. Black
dblack@wobblini.net

"trans. (T. Onoma)" <transami@runbox.com> writes:

···

On Monday 15 November 2004 08:45 am, David A. Black wrote:
>
> Yeah, as long as he doesn't choose 'virtual' :slight_smile:

He he. Seems like all the readily floated possibilities have poor
connotations. I've heard complaints about all three: 'virtual', 'meta', and
of course, 'singleton'. So what do others think of 'instance' class? Or more
to the point 'special' class -- a specialton :wink:

Personal class? (Every object has its own personal class.)

Yes, cause of singleton pattern.

T.

···

On Monday 15 November 2004 12:28 pm, Yukihiro Matsumoto wrote:

Hi,

In message "Re: Kernel#singleton_class" > > on Mon, 15 Nov 2004 22:45:31 +0900, "David A. Black" <dblack@wobblini.net> writes:
>> I guess it's probably best to let matz decide the name.
>
>Yeah, as long as he doesn't choose 'virtual' :slight_smile:

I'd call them singleton classes. Any objection?

       matz.

"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag news:2vrtthF2n19d2U1@uni-berlin.de...

Robert Klemme wrote:

The singleton class of f knows about instance methods defined in super
classes. Which is logical, considering this:

Ah, I was confusing instance_methods() with instance_methods(false).

accessors = h.keys - o.methods
class << o; self; end.send(:attr_accessor, *accessors)
h.each do |key, value|
  o.send("#{key}=", value) if accessors.include?(key)
end

Nice and short. But it has some drawbacks:
[...]

You would want ":bar" removed from the keys but it isn't because f.methods
returns an array of String. (I assume that symbols are the most likely
keys for the hash - which might be wrong.)

Hm, I assumed the hash would contain Strings as keys. I guess it could be normalized to that.

I'd prefer symbols - partly because they are more memory efficient and partly because method id's are symbols, too. (Yeah, I know that all #methods returns strings and send() et. al can deal with strings, too. But I prefer to think of an identifier as a symbol rather as a string.)

Plus, it's not selective enough IMHO because if you just have a setter,
then that is overwritten. And if you just have a getter, then no setter
is defined and you get an error during o.send("#{key}="...).

I was trying to work around methods in Kernel -- I don't think it makes sense to have o.p = when you don't have o.p.

Well, normall not. But the other way round is more likely to occur, i.e., you don't have a setter but you have a getter.

But I guess the check isn't strictly needed anyway. (attr_accessor :stuck_out_tongue: will create a public getter. I thought it would create a private one.)

Sorry, I'm not sure whether I understand what you mean here. Could you please explain a bit more?

Kind regards

    robert

  obj.class
  obj.own_class

You can rename it, but don't forget to rename

   rb_define_singleton_methods()
   rb_singleton_class_clone()
   etc,

also don't forget this strange T_SINGLETON that sometimes I see in the
doc.

Guy Decoux

"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.44.0411150600350.19936-100000@wobblini...

Hi --

> >
> > Yeah, as long as he doesn't choose 'virtual' :slight_smile:
>
> He he. Seems like all the readily floated possibilities have poor
> connotations. I've heard complaints about all three: 'virtual',

'meta', and

> of course, 'singleton'. So what do others think of 'instance' class?

Or more

> to the point 'special' class -- a specialton :wink:

In thinking about such things my mind always jumps to the question:
how easy (or not) will it be to explain to people? I think instance
class might be fairly good in that regard, but I'm not sure it's
logical. Why not "object class", since above all everything that has
one is an object? Which also means it's an instance, but why choose
that as its main identity? (Not that I like "object class"; I'm just
not sure that I'm seeing the reasoning behind "instance class".)

I'd also thought of "own class", as in:

  obj.class
  obj.own_class

What about obj.my_own_class? Ok, just kidding... :slight_smile:

(I'd actually prefer #class to be deprecated in favor of #birth_class,
so as to make a clearer pairing of, and distinction between, an
object's two classes. but I do not expect that to happen :slight_smile:

So am I.

Cheers

    robert

···

On Mon, 15 Nov 2004, trans. (T. Onoma) wrote:
> On Monday 15 November 2004 08:45 am, David A. Black wrote:

#object_class (like #object_id) would be nice. Then #class could be used by us
end programmers.

T.

···

On Monday 15 November 2004 09:04 am, David A. Black wrote:

(I'd actually prefer #class to be deprecated in favor of #birth_class,
so as to make a clearer pairing of, and distinction between, an
object's two classes. but I do not expect that to happen :slight_smile:

Hi,

···

In message "Re: Kernel#singleton_class" on Tue, 16 Nov 2004 02:54:13 +0900, "trans. (T. Onoma)" <transami@runbox.com> writes:

I'd call them singleton classes. Any objection?

Yes, cause of singleton pattern.

Hmm, any other alternative?

I don't prefer the terms "instance class" and "object class", just
because it's meaningless. Classes are naturally corresponding to
objects (or instances) in OOP. Besides, the word singleton used from
Lisp era, way older than design patterns, IIRC.

              matz.

trans. (T. Onoma) wrote:

···

On Monday 15 November 2004 12:28 pm, Yukihiro Matsumoto wrote:
> I'd call them singleton classes. Any objection?
>
> matz.

Yes, cause of singleton pattern.

Objection to the objection: The singleton pattern is not widely used in Ruby. Couldn't we rename the implementation of it? Maybe something like "SingleInstanceClass"?

trans. (T. Onoma) wrote:

> Hi,
>
> >> I guess it's probably best to let matz decide the name.
> >
> >Yeah, as long as he doesn't choose 'virtual' :slight_smile:
>
> I'd call them singleton classes. Any objection?
>
> matz.

Yes, cause of singleton pattern.

This doesn't bother me. We will almost always have the word "class"
or "pattern" following the word "singleton." No ambiguity. We do
sometimes talk about a Singleton (without the word "pattern"), but
then it is always capitalized.

There are also singleton methods; and I think some people refer to
objects that possess singleton methods as singletons. However, it's
always possible to clarify your meaning by the simple addition of
a single word.

I think the important thing is to know the meaning of the word
"singleton"; and then its specific meaning in context will be made
clear. (FWIW, it's used in card games also.)

Hal

···

On Monday 15 November 2004 12:28 pm, Yukihiro Matsumoto wrote:
> In message "Re: Kernel#singleton_class" > > > > on Mon, 15 Nov 2004 22:45:31 +0900, "David A. Black" > <dblack@wobblini.net> writes:

No, because of historical reasons, and the ability to distinguish
between two different uses of "singleton". (Besides, the Singleton
Pattern has fallen foul of OO purists.)

I say go for it, Matz.

Gavin

···

On Tuesday, November 16, 2004, 4:54:13 AM, trans. wrote:

On Monday 15 November 2004 12:28 pm, Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: Kernel#singleton_class" > > > > on Mon, 15 Nov 2004 22:45:31 +0900, "David A. Black" > <dblack@wobblini.net> writes:
>>> I guess it's probably best to let matz decide the name.
> >
> >Yeah, as long as he doesn't choose 'virtual' :slight_smile:
>
> I'd call them singleton classes. Any objection?
>
> matz.

Yes, cause of singleton pattern.