Get and Set in the same method?
BlitzMax Forums/BlitzMax Beginners Area/Get and Set in the same method?
| ||
I'm probably overlooking something simple, but here we go anyway. How can I have a method which allows me to both set and get a field ( or several fields ) of a type. For example : Type Ship Field XPos:Int,YPos:Int Method X() ' WHAT HERE? ' WHAT HERE? End Method End Type Local MyShip:Ship=New Ship MyShip.X(4) Print MyShip.X() I thought of using a default null integer for the parameter of the X Method, but since a null integer is equal to zero, that means I can't set the X Position to zero, so no go there. And before some bright spark says "forget the method, you only need to set or get the field", I know that, this is just a simple example. In the actual code, it won't actually be a field and I need to be able to both get and set with methods. Worse case, I can use two different methods, but it would be nice not to have to. |
| ||
Something like this maybe?Type Ship Field XPos:Int, YPos:Int Method DoIt( Action$, X Var, Y Var ) Select Lower( Action ) Case "set" XPos = X YPos = Y Case "get" X = XPos Y = YPos End Select End Method End Type Local MyShip:Ship=New Ship Local X, Y X = 4 Y = 7 MyShip.DoIt( "set", X, Y ) Local MyOtherShip:Ship=New Ship MyOtherShip.DoIt( "get", X, Y ) Print X Print Y MyShip.DoIt( "get", X, Y ) Print X Print Y |
| ||
What about something like:Const NullInt:Int = -2147483648 Type Ship Field XPos:Int,YPos:Int Method X:Int(Value:Int = NullInt) If Value <> NullInt XPos = Value End If Return XPos End Method End Type Local MyShip:Ship=New Ship MyShip.X(4) Print MyShip.X() I think it's pretty unlikely that you'll want to legitimately set a property to -2147483648. You could also do something similar for most other datatypes: Const NullString:String = "SomeGarbageThatYou'llNeverActuallySetAStringTo" Const NullLong:Long = -9223372036854775808 Const NullFloat:Float = whatever the min value is for float etc. And put these all in a common file that you include wherever needed. Can't see it working well for unsigned datatypes though (Short, Byte etc). |
| ||
Type Ship Field XPos:Int,YPos:Int Method X(XPos:int=-9999) if XPos = -9999 then return self.XPos self.XPos = XPos End Method End Type Its untested, but I was thinking that you would call it like this: X = MyShip.X() ' get X MyShip.X( 100 ) ' set X [edit] looks like I was a little slow and HappyCat have already suggested something similar. I think it would work just fine. |
| ||
Why not have separate set and get methods? I don't see any advantage in combining them. |
| ||
Thanks for the suggestions, guys. I think I'm going to go with Wendell's version, as I will have no control of the fields' contents. Therefore there is no way for me to prevent the field legitimately needing to be -9999, -9223372036854775808 or whatever else. Of course, if Null did what the documentation suggests it does, it would be ok. But despite the docs describing Null as a constant for an empty object instance, that only applies to custom types, it seems, not the inbuilt data types. I guess I can always make a feature request for that. Won't get it, but I can ask. Why not have separate set and get methods? I don't see any advantage in combining them. No particular reason other than it's cleaner when you're writing reusable code to have half the number of methods. A lot of libraries allow you to do this, and I like it. |
| ||
I do like this idea. I've started writing setters for all of my fields as standard but haven't yet come across a need for getters. I know it theory why you have them but can you guys give me any examples of how you use them? Shame you can do this Method X:Int(Value:Int = self.x) |
| ||
Use null instead of setting a specific value (null can be interpreted as an int)Type test Field _X:Int = 10 Method X:Int(val:Int=Null) If Not val=Null Then _X = val EndIf Return _X End Method End Type Local t:test = New test Print t.x() Print t.x(100) |
| ||
yeah.. but its interpreted as 0 so you can never set the value to 0. |
| ||
yeah, fair enough, I'll let you off this once ;) |
| ||
How about something like this ?Type Ship Field XVal:Int Method X:String( Value:String ) If Value = "get" Then Return Self.XVal Else Self.XVal = Value.ToInt() End If End Method End Type Test:Ship = New Ship Test.X( 50 ) Print Test.X( "get" ) |
| ||
I've been thinking about this today and I'm not sure I want methods with the same name as my fields where the only thing distinguishing them is a set of brackets. I'm not very disciplined when really powering through an idea and I think I'd forget them all the time (leading to hard to find bugs) I'll stick with SetX. (and possibly GetX if I can think of a good reason to implement Getters) When the new IDE is released I'd like to implement auto creation of these methods. |
| ||
Please tell me if i missed something with the Null Pointer, why does this set/return 0 :Type Ship Field XVal:Int Method X:Int( Value:Int = Null ) If Value = Null Then 'If you think it wont set it to 0 then just add, 'Value = 0 Return Self.XVal Else Self.XVal = Value End If End Method End Type Graphics 800,600, 0 Test:Ship = New Ship Test.X( 0 ) Print Test.X() While Not KeyHit( key_escape ) Cls DrawRect( Test.X(), 50, 100, 100 ) Flip Wend |
| ||
Beacuase Null is like a constant of 0 for ints. |