Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Private class members and some other comments


  • Please log in to reply
No replies to this topic
lancelot
  • Members
  • 20 posts
  • Last active: Feb 23 2014 01:35 AM
  • Joined: 16 Oct 2013

This is just some feedback on my experience with ahk classes. I have a class (code below) that loads a sorted list of strings from a file when an instance of the class is created and writes the modified list back to the file when the script exits.

 

First, it's very cool that classes can be used in this way to do the cleanup on exit. I was going to have different parts of a large script register their on-exit handlers and then have OnExit call each of them, but now I just have all the clean-up code packaged into classes.

 

The class can still be misused by accessing the member fields directly. I hope there'll be private class members in a future version. Then if my class can only be accessed through the interface functions, that'll be much more robust.

 

Also, it's very cool that the for loop can be made to work seamlessly by overloading _NewEnum. One comment is that for arrays NewEnum and _NewEnum are identical, but the for loop calls _NewEnum, so overloading NewEnum has no effect. Maybe NewEnum should just be removed.

 

One big catch is that strings consisting of digits are ambiguous, so obj.Remove(line) can decide to adjust other keys. And I cannot use Remove(line, "") because that doesn't work with non-digit strings! I think that's a known issue.

 

By the way, it's a bit annoying that ReadLine keeps the newline character. I think generally functions that read delimited records drop the separators.

; this script will overwrite the file c:\tempfile
; make sure your Swiss bank account number is stored elsewhere

xx := new logfile("c:\tempfile")
xx.Insert("foo")
xx.Insert("bar")
xx.Insert("baz")
xx := ""
xx := new logfile("c:\tempfile")
xx.Insert("bar")
xx.Remove("baz")
MsgBox, % "count: " xx.count()
for s in xx
	MsgBox, % s
	
class logfile {
	fname := "", nmsgs := 0, msgs := {}
	
	count() {
		return this.nmsgs
	}
	
	HasKey(key) {
		return this.msgs.HasKey(key)
	}
	
	Insert(key) {
		if (this.msgs.HasKey(key))
			return true
		this.nmsgs++
		return this.msgs.Insert(key, 1)
	}
	
	Remove(key) {
		ret := this.msgs.Remove(key)
		if (ret == 1)
			this.nmsgs--
		return ret
	}
	
	clear() {
		this.nmsgs := 0
		this.msgs := {}
	}
	
	_NewEnum() {
		return this.msgs._NewEnum()
	}
	
	__New(fname) {
		this.fname := fname
		if (!(file := FileOpen(fname, "r `n")))
			return this
		while (!file.AtEOF()) {
			line := file.ReadLine()
			if (SubStr(line, 0) == "`n")
				line := SubStr(line, 1, -1)
			this.Insert(line)
		}
		file.Close()
		return this
	}
	
	__Delete() {
		file := FileOpen(this.fname, "w `n")
		for line in this
			file.WriteLine(line)
		file.Close()
	}
}