Shortcut to refer to a type field?
BlitzMax Forums/BlitzMax Beginners Area/Shortcut to refer to a type field?
| ||
Is there a shortcut of some kind that lets you refer to fields of nested types easily without having to do loads of field.field.field.x ? I'm kinda new to using types. Didn't the original BlitzBasic have such a feature? e.g. Type mytype Field avar:Int End Type Type mytype2 Field bvar:mytype Field cvar:Int End Type Type mytype3 Field dvar:mytype2 Field evar:Int End Type Thing:mytype3=New mytype3 'How do I do this with less code: Print Thing.dvar.bvar.avar Is there some command that lets you refer only to the `mytype` fields? e.g. Print .avar? Or am I getting confused with `Self` and should be doing Object Oriented? |
| ||
Nope. No shortcut. |
| ||
There's no shortcut, but you'll find that normally things like this aren't too much of a problem. Not often, in the real world, if you're abstracted your design out, would you find going more than 1 deep. Sure sometimes you do, of course, but generally not. When you're working with an object, you call stuff etc on it's immediate fields, or maybe call a method on one of it's field objects. Aaron |
| ||
If you intend to use Thing.dvar.bvar.avar often in the same function, you could create a reference to bvar at the top:Local bvar:mytype=Thing.dbar.bvar bvar.avar=whatever |
| ||
Or use pointers. Something like:Type mytype Field avar:Int End Type Type mytype2 Field bvar:mytype Field cvar:Int End Type Type mytype3 Field dvar:mytype2 Field evar:Int End Type Local Thing:mytype3=New mytype3 Local a:Int Ptr = Varptr(Thing.dvar.bvar.avar) Print a[0] ' Thing.dvar.bvar.avar Which will save typing if you use it a lot. |
| ||
With TeaMonkey's example you could also use this to access other variables in the type, since bmax stores its types with the variables in the same order. For instance:Type mytype Field avar:Int Field fvar:Int End Type Type mytype2 Field bvar:mytype Field cvar:Int End Type Type mytype3 Field dvar:mytype2 Field evar:Int End Type Local Thing:mytype3=New mytype3 Thing.dvar=New mytype2 Thing.dvar.bvar=New mytype Thing.dvar.bvar.avar=5 Thing.dvar.bvar.fvar=10 Local a:Int Ptr = Varptr(Thing.dvar.bvar.avar) Print a[0] ' Thing.dvar.bvar.avar Print a[1] ' Thing.dvar.bvar.fvarA bit cryptic and dangerous if mark changes something but hey :) |
| ||
Using pointers is messy and will confuse the garbage collector - not recommended unless you have to. |
| ||
Whats wrong with doing it this way?Type mytype Field avar:Int End Type Type mytype2 Field bvar:mytype Field cvar:Int End Type Type mytype3 Field dvar:mytype2 Field evar:Int End Type Local Thing:mytype3=New mytype3 Thing.dvar=New mytype2 Thing.dvar.bvar=New mytype Local temp:mytype = Thing.dvar.bvar Print temp.avar |
| ||
Thanks Robert, you were the first one to clue me in on what I had in mind. I figured something like that was possible but I just couldn't see it. Setting a variable to the nested type will be very much what I need, thanks.. ie Local temp:mytype = Thing.dvar.bvar Print temp.avar (as in beakers example above). I just wanted to be able to go whatever.field, like relative to what type I wanted to work with, rather than give the whole absolute path. Thanks! The pointer method is interesting, you sure can do some sneaky things with those, but I think the variable shortcut will be just fine. |
| ||
Using pointers is messy and will confuse the garbage collector - not recommended unless you have to. Yeah, it's only worth using the pointer method for non-object types like Int. Objects are passed by reference anyway. |
| ||
Accessor methods. |
| ||
Exactly FlameDuck. AngelDaniel, don't use that crappy pointer solution (NO offense Rob - it worked, but really it's sort of going about things the hard way and circumventing the whole reference thing going on with BlitzMax). Not BlitzMax is here and offers a lot of new (Old) techniques for doing programming, use them. They have lots of advantages. Resorting to oldschool stuff will just make your job more of a pain in the arse. Make an accessor method. e.g. Have a method in mytype3 that gets you a mytype2. Then you just go Thing.bvar().avar=23 OR do this. Thing.setAvar(23) Thing.getAvar(34) These things should be methods anyway, cause accessing other Types' field sort of breaks the whole encapsulation thing just a tad. Aaron |
| ||
Do you mean somthing like the "With" command in actionscript:with (object) { _x = 50; _y = 100; }In BMX it might be: With Player.Sprite x = 50 y = 100 width = .5 height = .5 alpha = .5 End WithInstead of: Player.Sprite.x = 50 Player.Sprite.y = 50 Player.Sprite.width = .5 Player.Sprite.height = .5 Player.Sprite.alpha = .5 |
| ||
"with" (which is also in Pascal, BTW), has some subtle scoping issues. If you have a local or global named X, and also a field named X, then which one is referenced in the "with" block? It's easiest in Blitz Max to simply create another local variable, as others have mentioned above. It's neat and clean! |
| ||
That isn't a bad idea actually, it saves typing and looks a whole lot neater. |
| ||
Yes, I too would like to see with (although I can code perfectly well without it, it saves a lot of typing). |
| ||
Why would you go Player.Sprite.x and Player.Sprite.y? E N C A P S U L A T E Player.SetSpriteDetails(50,50,.5,.5,.5) In SetSpriteDetails(x,y,w,h,a) sprite.SetDetails(x,y,w,h,a) Aaron |
| ||
Um... an accessor method sounds all very well but personally I'm not going to add extra methods to a type just so that I can get access to a subtype, when it would be far less code and probably quicker to just do it the long way ie field.field.field etc. All very well adding all this OO stuff but not for the sake of it. |
| ||
It's not just for the sake of it. What if you decide to change your implementation later, and you get to that object a different way? If you've got an accessor method, then you just change it in one place and the rest of your code works. Good programming isn't about making it always quicker to implement. Think about maintenance, flexibility, reuse etc. Software engineering has changed over the years, for a reason. Someone just didn't invent this stuff cause they were being 'cute'. Sure if your program consists of plotting some points and making them go up and down, you might not bother. But any sort of large application benefits from strong design and impementation methods. Aaron |
| ||
Actually it's probably about the same ammount of code (and besides which any good IDE, will generate them automatically for you) and chances are it's actually going to be faster. Oh, and "what Aaron said". Again. |
| ||
"With" seems good. Oh, and I wasn't actually very serious about the whole pointer thing, its a very bad way to do it :) Just pointing out you can. Personally, overiding functions, private member types, and properties (I've said this in about 6 places to make sure someone in BRL sees it) are much more important. |