New Self
BlitzMax Forums/Brucey's Modules/New Self
| ||
BlitzMax NG doesn't seem to like this pattern, which is supported in BlitzMax BRL:Type MyException Function Make:MyException(code:Int, extra:Object = Null) Local e:MyException = New Self ' <--- Syntax error: expecting identifier e._code = code ; e._extra = extra Return e End Function Function Raise(code:Int, extra:Object = Null) Throw Self.Make(code, extra) ' <--- Illegal use of Self within static scope End Function End Type It's not an accidental feature; BlitzMax BRL supports Self for types in the logically-expected contexts and gives clear error messages (referring to the fact that they're not Objects) if you misuse them, so it was definitely designed this way. Can this be implemented? (For that matter, is reaching 1:1 with BlitzMax BRL on minor issues like this considered a goal, or a nuisance?) I notice that the second message also indicates that NG has consciously made a decision on this matter, but it's a different one from BRL. Correcting a perceived bug, or simply an independent design choice? I use this a lot; it seems like better style than explicit repetition. Good if it's long, too. |
| ||
Can this be implemented? Sure :-) Would you like to open an issue? ( https://github.com/bmx-ng/bcc/issues ) |
| ||
Thanks! Opened. |
| ||
Aside the bug: nice idea, really saves typing long typenames. A pity this does not work for return types (method get:self()) - would save some writing when else having to override methods just to return the extended type instead of the original one. Current Type TBaseClass Field x:int End Type Type TExtendedClass extends TBaseClass Field extendedProperty:int End Type Type TBaseClassCollection global instance:TBaseClassCollection Function GetInstance:TClassCollection() return instance End Function Method GetChild:TBaseClass(guid:string); ...;Return child; End Method End Type Type TClassCollection extends TBaseClassCollection Function GetInstance:TClassCollection() 'handle potentially needed collection conversion from base collection ... return TClassCollection(instance) End Function Method GetChild:TExtendedClass(guid:string); ...;Return TExtendedClass(Super.GetChild(guid); End Method End Type I use similar constructs for various collections (as vanilla does not allow interfaces - and I need to avoid cyclic dependencies - which enforces me to have base classes to refer to, and implementations/extended classes to specialice behaviour). Without overriding "GetChild" you will have to "cast-verify-type" on your own, also this allows chaining: TBaseClassCollection.GetInstance().GetChild("bla").x TClassCollection.GetInstance().GetChild("bla").extendedProperty @Yasha Is there some simple way to simplify above's approach? Something similar to the "new self" 'secret' I do not know? bye Ron |
| ||
Not one I can think of, sorry. To be honest I tend to do the opposite, work a lot with Object and Invoke. My own de-facto solution regarding interfaces in the BRL compiler (not currently using my own Interface patch in production, perhaps I should) is to do something like: Type IFooBar Final Function Foo(_self:Object) Local _foo:TMethod = TTypeId.ForObject(_self).FindMethod("Foo") If _foo Then _foo.Invoke(_self, Null) End Function Function Bar:Int(_self:Object, x:Int) Local _bar:TMethod = TTypeId.ForObject(_self).FindMethod("Bar") If _bar Then Return Int(String(_bar.Invoke(_self, [Object(String(_self))]))) End Function End Type Function Implements:Int(o:Object, i:String) Local t:TTypeId = TTypeId.ForName(i) If t.ExtendsType(ct) Then Return True While t <> ObjectTypeId If t.Metadata(i) Then Return True t = t.SuperType() Wend Return False End Function Type A { IFooBar } Method Foo() Print "A foo" End Method Method Bar:Int(x:Int) Print "A bar received " + x End Method End Type IFooBar.Foo(New A) ...etc. It's not very formally codified actually. Lucky thing performance isn't an issue for my code. |
| ||
While this is surely not the worst approach, I think there must exist something "easier" (the invokation is a bit ... hmm... hard to read). Using Reflection might be a bit "heavy" (albeit I do not know the impact but loosely remember, that there was some talk about it, when Mark introduced it to BlitzMax). Once NG is doing all I need (read: works and the modules compile fine :-) it might be a good chance to cut loose ends and to switch things to use "interfaces" (which Brucey nicely implemented in NG already)... Feel free to come up with other ideas :-) bye Ron |
| ||
Thanks for changing this. (Took me an embarrassingly long time to work out that the fix was applied to a different branch.) Now more of my project compiles, I have more incompatibilities to report... which I'm sure is delightful news. I'll do that over at the issues list. |