Open Hovestar opened 4 years ago
Just following up on this since it piqued my interest again, the fix I had listed causes an issue since if the meta class is undefined there's a ()
embedded in the code that's invalid, a proper fix is this:
oClass := iif( <.metaClass.>, <metaClass>(nil), HBClass()):new( <(ClassName)>, __HB_CLS_PAR( [ @<SuperClass1>() ] [ , @<SuperClassN>() ] ), @__HB_CLS_OPT([__HB_CLS_ASID(<FuncName>),] <ClassName>)() [, <.modulfriend.> ] ) ;;
In hbclass.ch (https://github.com/harbour/core/blob/master/include/hbclass.ch) currrently metaclasses are defined like so:
oClass := iif( <.metaClass.>, <(metaClass)>, HBClass():new( ... ) ) ;;
This means that upon preprocessing a normal class gets turned into something like this:to
...;s_oClass := IIF(.T., "meta", HBClass():New( "test" , { HBObject():Classh } ) );
instead of the (I think expected)...;s_oClass := IIF(.T., meta(), HBClass()):New( "test" , { HBObject():Classh } ) ;
I believe that the correct directive is this (just moving+adding a paren and removing the smart stringify):
oClass := iif( <.metaClass.>, <metaClass>(), HBClass()):new( ... ) ;;
Otherwise the only runtime correct way to use meta classes it to specify classes like so:
and it ignores all super classes that you specify unless you manually add them to the array with HBObject.
That all said, the use of metaclasses is extremely rare (likely non existent considering this) and this change may break backwards compatibility in a way where issues only manifest at runtime.