[chuck-users] Casting behaviour

Gonzalo gonzalo at dense13.com
Fri Oct 17 17:42:44 EDT 2014


On 18/10/2014 1:40 am, Michael Heuer wrote:
> Gonzalo wrote:
>> I have this (unexpected?) behaviour when casting. I can cast a object to its
>> parent class, but the methods that get executed are still their own (and
>> viceversa). I.e.:
>>
>> ----------------------------------
>> public class Parent {
>>    fun void test() {
>>      <<< "Parent" >>>;
>>    }
>> }
>>
>> class Child extends Parent {
>>    fun void test() {
>>      <<< "Child" >>>;
>>    }
>> }
>>
>> Parent p;
>> Child @ ch;
>> p $ Child @=> ch;
>> ch.test(); // prints Parent
>
> This shouldn't work, because p !instanceof Child, the cast should be a
> compiler error.

Thanks Michael. You're right, and in fact it doesn't work at all. Now 
that I've tried, ch can not call methods exclusive to Child either 
(Assertion failed: (m_offset < obj->vtable->funcs.size()), function 
execute, file chuck_instr.cpp, line 4765).


>> Is this intended behavior? What's the point of casting then?
>
> I typically only use casting when pulling object references out of
> data structures that hold arrays of Object references, e.g. an
> ArrayList
>
> https://github.com/heuermh/lick/blob/master/Freeze.ck#L73

Of course, I see. I was trying to use casting to bypass the lack of 
constructors, bad misuse.


>> I might describe too what I'm trying to do, maybe there's a better approach.
>> I have a .create method in Parent that returns a Parent object, and I wanted
>> to create that same method in Child, but I can't do it because the arguments
>> are the same, and it won't let me overwrite the method when only the return
>> type changes. So to create a child with the .create method, I do this:
>>
>> Parent.create(...) $ Child @=> Child ch;
>>
>> Which works, but then it still behaves as a parent, so it defeats the whole
>> purpose.
>
> Having proper constructors in ChucK would help here
>
> https://github.com/spencersalazar/chuck/issues/32
>
>
> A workaround might be to include the classname in your create methods
>
> class Parent {
>    fun static Parent createParent(...) { }
> }
>
> class Child extends Parent {
>    fun static Child createChild(...) { }
> }

Yes, that might be the way to go. I use init() methods as a workaround 
for constructors, so my normal instantiations look like:

MyClass c;
c.init(...);

Not very nice, which is why I was trying to have the static 'create' 
methods. I'm thinking of having a global Make class, and put all my 
static initializers there. Which would look something like:

class Make {
   fun static Parent Parent(args) {
     Parent p;
     p.init(args);
     return p;
   }
   ....
}

Make.Parent(...) @=> Parent p;

Ugly class, but nicer to call than Parent.createParent(args) ?



>
>     michael
> _______________________________________________
> chuck-users mailing list
> chuck-users at lists.cs.princeton.edu
> https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
>


More information about the chuck-users mailing list