Hi
obj.class = MyClass
Is it harmful?
rolo
Hi
obj.class = MyClass
Is it harmful?
rolo
irb(main):002:0> {}.class = Array
NoMethodError: undefined method `class=' for {}:Hash
from (irb):2
irb(main):003:0>
Sean O'Dell
On Thursday 24 June 2004 16:15, rolo wrote:
Hi
obj.class = MyClass
Is it harmful?
I don't know -- is NoMethodError considered harmful? ![]()
If you are so inclined, http://evil.rubyforge.org has an
implementation of Object#class=
--- rolo <rohitlodha@hotwireindia.com> wrote:
Hi
obj.class = MyClass
Is it harmful?
rolo
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail
I can't possibly imagine it being useful to do this except when the objects have very similar, if not identical, instance variables. And in cases where this is true we have these things we call polymorphism and inheritance. Lets say you have a parent class of animal with two subclasses cat and dog. But both cat and dog have the same data. Name, gender, breed, color, etc. There should never be a need to turn a cat into a dog or vice versa. If you are programming properly you would only deal in objects of type animal. If by some strange change a dog turned into a cat through genetic engineering you would simply make a new instance of object cat and copy the data from the former dog object into it. Then delete the dog object. It is only in this one case that I see your example being slightly useful, but only for code saving reasons. If someone else has more insight I would love to hear it.
-Scott
rolo wrote:
Hi
obj.class = MyClass
Is it harmful?
rolo
Even if there was a #class= for objects, it ranks up there with goto in
limited usefulness. Yes, it can be useful, but if you're using it,
you're probably being too clever.
Sean O'Dell (sean@celsoft.com) wrote:
On Thursday 24 June 2004 16:15, rolo wrote:
> Hi
>
> obj.class = MyClass
>
> Is it harmful?irb(main):002:0> {}.class = Array
NoMethodError: undefined method `class=' for {}:Hash
from (irb):2
irb(main):003:0>
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
Scott Rubin said:
I can't possibly imagine it being useful to do this except when the
objects have very similar, if not identical, instance variables.
The "standard" application for the self.class= method (aka become(class))
is use it to do demand on load style proxies. Suppose you have a largish
object in external storage (database, file, whatever). You create a
small, efficient proxy item for the large object until you really need the
true data in the object. Then you load the object and let the proxy
"become" the newly loaded object.
Without class=/become methods,
(a) the proxy remains and forwards all messages to the real object, or
(b) you replace every reference in the program to the proxy with
a reference to the real object.
(a) is a small, but anoying constant cost, and (b) may be difficult,
depending on how wide spread the proxy was used.
That's why class=/become would be attractive, despite its technical
difficulties and mildly worrisome semantices.
--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
I knew it was evil, I think it should be norm.
PS I know it is not allowed, but is it so for tech reasons?
Regards,
Rohit
Sean O'Dell (sean@celsoft.com) wrote:
> On Thursday 24 June 2004 16:15, rolo wrote:
> > Hi
> >
> > obj.class = MyClass
> >
> > Is it harmful?
>
> irb(main):002:0> {}.class = Array
> NoMethodError: undefined method `class=' for {}:Hash
> from (irb):2
> irb(main):003:0>Even if there was a #class= for objects, it ranks up there with goto in
limited usefulness. Yes, it can be useful, but if you're using it,
you're probably being too clever.
sounds like an RCR for Object#tie
-a
On Fri, 25 Jun 2004, Jim Weirich wrote:
Scott Rubin said:
I can't possibly imagine it being useful to do this except when the
objects have very similar, if not identical, instance variables.The "standard" application for the self.class= method (aka become(class))
is use it to do demand on load style proxies. Suppose you have a largish
object in external storage (database, file, whatever). You create a
small, efficient proxy item for the large object until you really need the
true data in the object. Then you load the object and let the proxy
"become" the newly loaded object.Without class=/become methods,
(a) the proxy remains and forwards all messages to the real object, or
(b) you replace every reference in the program to the proxy with
a reference to the real object.(a) is a small, but anoying constant cost, and (b) may be difficult,
depending on how wide spread the proxy was used.That's why class=/become would be attractive, despite its technical
difficulties and mildly worrisome semantices.--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen
===============================================================================
I don't think it would be difficult at all. In fact, think of what Ruby has
to go through when you make a class into a singleton with:
obj<<class
end
It has to pull forward all the methods of the object's class into a new
anonymous singleton class for the object. That's a lot more work than simply
pointing the object's class to a different class that's already defined with
all of its methods and such.
It should be very easy to do. I'm wondering if a C extension could possibly
even do this.
Sean O'Dell
On Friday 25 June 2004 06:32, Jim Weirich wrote:
That's why class=/become would be attractive, despite its technical
difficulties and mildly worrisome semantices.
Jim Weirich wrote:
The "standard" application for the self.class= method (aka become(class))
is use it to do demand on load style proxies. Suppose you have a largish
object in external storage (database, file, whatever). You create a
small, efficient proxy item for the large object until you really need the
true data in the object. Then you load the object and let the proxy
"become" the newly loaded object.Without class=/become methods,
(a) the proxy remains and forwards all messages to the real object, or
(b) you replace every reference in the program to the proxy with a reference to the real object.(a) is a small, but anoying constant cost, and (b) may be difficult,
depending on how wide spread the proxy was used.
There's another small, but annoying problem with the proxy-approach: There are operations which can't be forwarded. I can only think of the truth value of an Object right now.
It's a problem in this case:
irb(main):001:0> [obj = false, ref = WeakRef.new(obj)]
=> [false, false]
# We should now be able to treat obj and ref as
# if they were actually the same thing
irb(main):002:0> [obj.to_s, ref.to_s]
=> ["false", "false"] # This is okay, methods get forwarded
irb(main):003:0> [if not obj then "foo" end, if not ref then "foo" end]
=> ["foo", nil] # truth value decisions can't be forwarded
irb(main):004:0> exit
I'm not sure how other languages handle -- as far as I know Perl has a way of overloading how Objects will be converted into Boolean values.
Python also seems to have this via __nonzero__. (And __len__ == 0)
I have no idea however if such a method (let's call it #to_bool) could be do in a way such that it doesn't disturb the performance of all Ruby scripts, but it looks more possible every day.
Regards,
Florian Gross
Good question. I am personally having trouble thinking of a good reason why a
programmer couldn't change the class of an object. Except for possible
problems when a different set of methods suddenly gets a set of instance
variables it might not expect (buyer beware), it seems like we ought to be
able to do that. I don't believe there's any solid technical block to doing
this, is there?
Sean O'Dell
On Thursday 24 June 2004 17:23, rolo wrote:
> Sean O'Dell (sean@celsoft.com) wrote:
> > On Thursday 24 June 2004 16:15, rolo wrote:
> > > Hi
> > >
> > > obj.class = MyClass
> > >
> > > Is it harmful?
> >
> > irb(main):002:0> {}.class = Array
> > NoMethodError: undefined method `class=' for {}:Hash
> > from (irb):2
> > irb(main):003:0>
>
> Even if there was a #class= for objects, it ranks up there with goto in
> limited usefulness. Yes, it can be useful, but if you're using it,
> you're probably being too clever.I knew it was evil, I think it should be norm.
PS I know it is not allowed, but is it so for tech reasons?
Or class=.
Sean O'Dell
On Friday 25 June 2004 08:03, Ara.T.Howard wrote:
sounds like an RCR for Object#tie
It should be very easy to do. I'm wondering if a C extension could possibly
even do this.
You are right, a C extension can effectively crash ruby
Read carefully hash.c and array.c and just imagine what will be the result
if one method of hash.c will be applied to an array.
matz has one day say it in a message to ruby-talk : one information is
missing
Guy Decoux
Florian Gross said:
There's another small, but annoying problem with the proxy-approach:
There are operations which can't be forwarded. I can only think of the
truth value of an Object right now.
Comparisons are problematic because the first line of a comparison is
often "Are you the same class as me?". Proxies arent't the right class so
the comparisons fail.
Actually, rather than a become or class= method, I would be interested in
a swap_identitys method. For example, to make a proxy object real ...
def make_real
obj = read_real_object_from_the_database
swap_identities(self, obj)
end
When identities are swapped, every reference in the system to the first
object will magically become a reference to the second object, and
vice-versa.
There are no semantic problems with an object suddenly changing classes
and finding inappropriate member variables. They just switch identities.
This would be perfect for the proxy problem.
Although it solves semantic problems of become, I doubt it would still fly
with Ruby as it is today. All objects would have to occupy the same
amount of memory for this to work (amoung other constraints). I don't
think that's true of many of the built in classes.
--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
Sean O'Dell wrote:
Good question. I am personally having trouble thinking of a good reason why a programmer couldn't change the class of an object. Except for possible problems when a different set of methods suddenly gets a set of instance variables it might not expect (buyer beware), it seems like we ought to be able to do that. I don't believe there's any solid technical block to doing this, is there?
Sean O'Dell
It would be nice to have in real life too. Just imagine: you hold an apple in your hand and suddenly it turns into a piece of gold. I would not mind ![]()
Gennady.
That's exactly the problem -- by forcing one object into another
class, you require that one or both classes have sufficient knowledge
of the internal data representation of the other to be able to safely
make the switch. That kind of low-level manipulation usually stays
within a class for a reason.
The only real reason I can see to dynamically change the class of an
object would be in languages where there are static type constraints
that have to be satisfied. As it is, in Ruby, you can always just wrap
the original object in a proxy, or access it through an adapter that
supports all the public methods of the new class; it fits the "duck
typing" rule, without breaking encapsulation.
Lennon
variables it might not expect (buyer beware), it seems like we ought to be
able to do that. I don't believe there's any solid technical block to doing
this, is there?
If you think that the possiblity to crash ruby is not a technical reason,
then you are right it don't exist solid technical reason.
Guy Decoux
You can do all sorts of things with Ruby, I see no reason why changing an
object's class would crash Ruby anymore than, say, redefining a method to
something different than an object expects, or including modules in a class
that don't belong there. Just be careful of what you're doing. I see no
FUNDAMENTAL reason why you couldn't change an object's class.
Sean O'Dell
On Friday 25 June 2004 09:15, ts wrote:
> It should be very easy to do. I'm wondering if a C extension could
possibly S> even do this.You are right, a C extension can effectively crash ruby
Read carefully hash.c and array.c and just imagine what will be the result
if one method of hash.c will be applied to an array.matz has one day say it in a message to ruby-talk : one information is
missing
Jim Weirich wrote:
Florian Gross said:
[problems with proxies]
Comparisons are problematic because the first line of a comparison is
often "Are you the same class as me?". Proxies arent't the right class so
the comparisons fail.
It depends -- the answer to that question can be overloaded in most cases. (Though Object.instance_method(:class).bind(obj).call will always give you the real class and I think that some of the internal methods actually do something like that.)
Actually, rather than a become or class= method, I would be interested in
a swap_identitys method. For example, to make a proxy object real ...def make_real
obj = read_real_object_from_the_database
swap_identities(self, obj)
endWhen identities are swapped, every reference in the system to the first
object will magically become a reference to the second object, and
vice-versa.
This is how Squeak implements this AFAIK -- it just iterates through all Object references and changes them.
I'm not sure, but this could be a bit slow, maybe. (And I'm not sure if it would be a general solution for the problems with Proxy objects -- it would work in the lazy database example, but there might be other problematic use cases.)
Regards,
Florian Gross
Heya,
Lennon Day-Reynolds wrote:
That's exactly the problem -- by forcing one object into another
class, you require that one or both classes have sufficient knowledge
of the internal data representation of the other to be able to safely
make the switch. That kind of low-level manipulation usually stays
within a class for a reason.
That's why there are the _generic functions_ CHANGE-CLASS and UPDATE-INSTANCE-FOR-DIFFERENT-CLASS in Common Lisp.
The only real reason I can see to dynamically change the class of an
object would be in languages where there are static type constraints
that have to be satisfied. As it is, in Ruby, you can always just wrap
the original object in a proxy, or access it through an adapter that
supports all the public methods of the new class; it fits the "duck
typing" rule, without breaking encapsulation.
Another reason would be that it might be useful to change the object _in place_. That is, all existing references suddenly point to the new object.
Cheers,
Michael