OK, so I still don't get properties!
Monkey Archive Forums/Monkey Discussion/OK, so I still don't get properties!
| ||
I noticed Samah's recent post about properties, and that reminded me that I'd never quite grasped what they did differently to a plain method. A quick search turns up an example, also from Samah, which looks like this:Class Foo Private Field bar:String Public Method Bar:String() Property Return bar End Method Bar:Void(bar:String) Property Self.bar = bar End End Function Main:Int() Local f:Foo = New Foo f.Bar = "Hello World!" Print f.Bar Return 0 End I get what this does, and I get the practise of providing a particular way of accessing fields, but what I don't get is why the above is different to this: Class Foo Private Field bar:String Public Method Bar:String() Return bar End Method Bar:Void(bar:String) Self.bar = bar End End Function Main:Int() Local f:Foo = New Foo f.Bar = "Hello World!" Print f.Bar Return 0 End (I've simply removed the keyword Property.) I simply haven't managed to pick up on what Property actually does! Lastly, and mostly off-my-own-topic, while trying to figure it out, I unexpectedly found I could do this -- surely a bug? Class Test Method Whatever (anything:String) Print anything End End Function Main () Local t:Test = New Test t.Whatever "Hello" t.Whatever = "Hello" ' WTF?! End Oh, and another thing! Running Samah's original example in STDCPP gives two warnings, though it still works: main.cpp: In constructor 'bb_untitled1_Foo::bb_untitled1_Foo()': main.cpp:913:16: warning: attempt to free a non-heap object 'null' [enabled by default] main.cpp: In function 'int bbMain()': main.cpp:913:16: warning: attempt to free a non-heap object 'null' [enabled by default] Is this something that might need to be looked at by Mark? |
| ||
I am not sure I get it completely myself but I think this is how it works: when you declared the method as a property, the value can be assigned with the equal while the other way it would have to be assigned through the method parenthesis take your code for example: Method Whatever (anything:String) Print anything End for that, you would have to call the method like so: t.Whatever("Hello") or t.Whatever "Hello" but if you had declared the Method as such: Method Whatever (anything:String) Property Print anything End you can now call it with the equal: t.Whatever = "Hello" note that Samah created two methods one to pass it to the method: Method Bar:Void(bar:String) Property Self.bar = bar End and one to return from the method: Method Bar:String() Property Return bar End the second one will have to be created to return a value from the method. I haven't tested it with Functions but I guess it works the same way. I guess is a way for method to be represented as a variable. |
| ||
Properties are generally used to expose private fields and to let the developer do some magic calculations in the background. Here's some code inspired by a C# example: Basically this lets you set the value in hours as if it were a variable, but it actually stores it internally in seconds. Then you can use the other properties to read the value in other formats. Edit: As for this code working without the Property keyword, I would call that a bug. f.Bar = "Hello World!" It should really fail compilation. I also don't like the fact that you can omit parentheses in method calls. To be honest, the Monkey syntax is much too lazy for my tastes. "Optional" syntax promotes lazy coding, in my opinion. |
| ||
As for this code working without the Property keyword, I would call that a bug. +1 Maybe we should raise a bug report to Mark? |
| ||
Another use for properties is pure semantics. When using reflection in Java (which doesn't have properties) there's no way to tell if the get/set method you just found was actually a property or just an unfortunately named method. Anyone who's worked with Java/Spring Beans and EL will tell you this is huge pain in the ass. In C# (which does have properties), you never get the two mixed. As for Monkey, it's hard to say what you absolutely *need* them for, apart from using the assignment operator as convenience (and readability), which seems to work regardless. |
| ||
What's the difference between a property and an 'unfortunately named method'? Aren't they still just get and set methods with different syntax? |
| ||
Thanks all... I'll have to mess around a little and see whether or not it makes much practical difference to me. I have to say, I thought there would be more to properties than this! I suppose this controlled-access stuff might mean more if you're a professional/serious coder using intellisense to bring up objects' "public" fields/methods as a way of seeing what you have access to without referring to the docs, and stuff like that, assuming such a system would skip the presentation of private fields, etc. I also don't like the fact that you can omit parentheses in method calls Yeah, I used this a fair bit early on, but I've reverted to using brackets, at least when returning values from functions/methods. I'll go post the Method = String thing as a bug. Thanks again. |
| ||
What's the difference between a property and an 'unfortunately named method'? The latter may not be a property (i.e. something which reflects the state of the object). |
| ||
Remember you can inherit Properties and have them in Interfaces :) And you can do stuff like: Method On:Bool() Property return isOn End Method Off:Bool() Property return Not isOn Or list.Length = 0 End Not that above is a good example, but I just wanted to point out that you can make you logic look more sane sometimes using properties - even tough it just returns a field. btw I wrote a tutorial on Properties and another on Generics many months back, but I could not find it using search? |
| ||
Method On:Bool() Property return isOn End Method Off:Bool() Property return Not isOn Or list.Length = 0 End See, I still don't get the difference, at least compared to this: Method On:Bool() return isOn End Method Off:Bool() return Not isOn Or list.Length = 0 End With Monkey, you don't even have to use brackets for methods, so calling either would look exactly the same (I think!), eg. If myobject.On Then Print "Hello" So, all I've gathered about properties is that you can provide the illusion of reading from or writing to a field (albeit in a 'safe' way), but other than the calling syntax, is that the only difference? |
| ||
The usage. A property should represent a status in a class. A method should perform actions. As instance, in a GUI library, the X and Y position of a window can be properties, so when you modify the values, the internal API calls to move the window are called. Example using properties (x is a property) myWindow.X+=1 Example not using properties, but using get / set: myWindow.SetX(myWindow.GetX()+1) Example using field + method: myWindow.x+=1 myWindow.RefreshPosition() From my point of view, it is obvious that a property approach is much more clean and nice. |
| ||
I totally agree with Ziggy You can do stuff like: If myVector.Length < 10 Even cooler is that you can now also go: myVector.Length = 40 My example was just for SET, but you can do GET properties aswell like Ziggy did, like this: Method SState:Bool() Property Return state End Method State:Void( value:Bool) Property state = value End 'close Door.Open = False 'open Door.Open = True 'Check If Door.Open ' In this case (if it is appliciable to the game) you might want to check Close as well. So you can go: If Door.Close 'Or Door.Close = True All based on a isClosed:Bool or something more advanced. Actually since you use proper OOP abstraction (you do not access the object directly, only throught the interface) you can change that bool into a complex event system or something without changing the Open/Close Property |