[chuck-users] Casting behaviour

Michael Heuer heuermh at gmail.com
Fri Oct 17 17:53:42 EDT 2014


Gonzalo wrote:
> 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.

Yep, that's very similar to what I do, init() method + static create
methods, for example

https://github.com/heuermh/lick/blob/master/Freeze.ck#L159


> 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) ?

That's not a bad idea.

The reason I grumble about not having constructors is that for most
stuff I can just do

adc => Foo foo => Bar bar => dac;

but the classes that require special initialization I have to remember to do

Baz.create() @=> Baz baz;
Qux.create() @=> Qux qux;

adc => baz => qux => dac;

because

adc => Foo foo => Bar bar => dac;

foo.init();
bar.init();

might not necessarily work.

   michael


More information about the chuck-users mailing list