Hello all,
A newbie here. I have been learning Nim using the online tutorials and is thoroughly enjoying Nim . I have completed the part 1 and have advanced to Part 2 of the tutorial. Have a question regarding the setter methods discussed in the 'Properties' section of the tutorial. Can you please help.
The code looks like this. It appears like s.host = 34 is not calling the setter proc. At the same time , s.`host=` 34 calls the setter proc.
Also is there a facility in Nim to mark class variables as Private/Public? Thanks in advance.
Edit - Aplologies, there was an error in my program, corrected now. My question still stands,
Nim Compiler Version 0.17.0 (2017-05-18) [MacOSX: amd64]
type
Socket = ref object of RootObj
host: int # cannot be accessed from the outside of the module due to missing star
proc `host=`(s: var Socket, value: int) {.inline.} =
## setter of host address
echo "inside the getter host method"
s.host = value
proc host(s: Socket): int {.inline.} =
## getter of host address
s.host
var s: Socket
new s
s.host = 34 # => does not call the host= method. "inside the getter method" string is not printed
s.`host=` 34 # => works as expected. host= method is called.
But Nim seems to consciously embrace ambiguity to accomplish separation of concerns: I can write a.host in another module and not give a damn about whether this accesses a field or calls a proc which returns the value of a field and I like that. I don't want to know what encapsulation model the module I use has, I just want to use it. Much better than Java's getter/setter scheme.
Also having to use a tweaked field name inside the module would feel bad to me. Maybe a big fat ambiguity warning instead of an error would do.
A solution might be to make Nim reverse preferences in the above ambiguity: use the setter if there is one, else use the assignment.
Edit: of course the latter rule would need an exception for code inside the setter itself, which would be really strange.
@Lando I think you misunderstood me. I like properties for the reasons you mentioned (mainly: not giving a damn). I just don't like the fact they work differently in the module the type is defined in. ;)
As for whether properties are good: it depends. Memoized properties are often a good usecase: after the first access it actually is just a simple read (although one could argue that as the very first call is expensive, it should not mimic simple access). Also, properties can be an alias --- in one of my projects I used some generic N-spaces but aliased a few first elements of any N-dimentional array by x, y, z etc.
As for solution: why not use the same one as with assignments? system.`host=`(s, 34) sounds weird but hey, it IS weird to directly access a field when a setter for this field is defined!