Why should initialize_copy verify the class of the original?

J

Jeremy Henty

I was looking at the CD player example in the Pickaxe book and I can't
see why their C implementation of CDPlayer#initialize_copy needs to
check that the original object is an instance of CDPlayer . Isn't
this always the case? If #initialize_copy is only called from inside
#dup or #clone then surely the receiver has to be of the same class as
the original! What am I missing?

Regards,

Jeremy Henty
 
S

SonOfLilit

I can call initialize_copy too, here:

object.initialize_copy

Ha! I've fooled this object!

In Ruby, you can always do anything. No, really.

If $SAFE isn't used (which is mostly the case), every bit of code can
do ANYTHING to the program state.

So that initialize_copy sanity test makes sense (personally, I'm not
sure I would've done it, but it makes sense).


Plug: Check the adopt-a-newbie thread in ruby-talk.
 
J

Jeremy Henty

I can call initialize_copy too, here:

object.initialize_copy

Well, actually you *can't*:

==> NoMethodError: private method `initialize_copy' called for ...

:) but I take your point (and you can work round "private" with
#instance_eval ). But can it ever be called with an object of the
wrong type unless the user explicitly does so?
If $SAFE isn't used (which is mostly the case), every bit of code can
do ANYTHING to the program state.

That's true for Ruby variables, method calls etc., but hopefully we
can ensure the C internals are not corrupted. I was thinking I could
at least rely on the method being called with objects of the right
type, but as you pointed out that's not true.
So that initialize_copy sanity test makes sense (personally, I'm not
sure I would've done it,

I didn't do it either when I implemented color classes for Ruby/FLTK.
I haven't managed to get a segfault out of it, but I can certainly
corrupt objects. One more for the bug list...

Thanks for the answer, I'm a little embarrassed not to have thought of
it before posting.

Jeremy Henty
 
D

David Vallner

I was looking at the CD player example in the Pickaxe book and I can't
see why their C implementation of CDPlayer#initialize_copy needs to
check that the original object is an instance of CDPlayer . Isn't
this always the case? If #initialize_copy is only called from inside
#dup or #clone then surely the receiver has to be of the same class as
the original! What am I missing?

CDPlayer.new.instance_eval {initialize_copy(TeddyBear.new)}

Which would probably cause the C implementation to do Bad Things without
said check.

David Vallner
 
J

Jeremy Henty

[...] If #initialize_copy is only called from inside #dup or #clone
then surely the receiver has to be of the same class as the
original! What am I missing?

CDPlayer.new.instance_eval {initialize_copy(TeddyBear.new)}

That's the conclusion we came to in the other thread (though it wasn't
written down explicitly as you did here).
Which would probably cause the C implementation to do Bad Things
without said check.

Yes, if the instances of the CDPlayer and TeddyBear classes are T_DATA
objects that wrap (CDPlayer *) and (TeddyBear *) pointers, then this
code will coerce a (TeddyBear *) to a (CDPlayer *). Hilarity may well
ensue.

Incidentally the Pickaxe is (IMHO) a little misleading on this point,
it describes Data_Get_Struct as "a type-safe wrapper around the macro
DATA_PTR(obj)". In fact it's only type-safe with respect to the TYPE
of obj , it's not type-safe with respect to the type of the C pointer
that obj wraps.

Regards,

Jeremy Henty
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,114
Latest member
GlucoPremiumReview
Top