let counter = setmeta({
count = 0
}, {
__type = "counter"
__tostring = fn (self) {
return "%s(%s)":format(type(self), self.count)
}
__call = fn (self) {
raw_set(self, "count", self.count + 1)
return self.count
}
__get = fn (self, key) {
return raw_get(self, key)
}
__set = fn (self, key, value) {
if key == "count" {
error "can not change counter manually"
} else {
raw_set(self, key, value)
}
}
})
print(type(counter)) # counter
print(counter) # counter(0)
print(counter()) # 1
print(counter) # counter(1)
print(counter()) # 2
print(counter) # counter(2)
print(counter()) # 3
print(counter) # counter(3)
print("counter.count =", counter.count) # counter.count = 3
counter.a = false
print("counter.a =", counter.a) # counter.a = false
counter.count += 1 # ERROR: can not change counter manually