new decorator

4 views
Skip to first unread message

Sergey Schetinin

unread,
Jul 25, 2009, 1:13:03 PM7/25/09
to better...@googlegroups.com
I've just committed a small but very useful change. It has two parts
1. @compute can have an additional parameter:
@compute(write_to='attr') When it's specified you can set compute
attributes, but the set will be redirected to the specified attr.
2. @attr.writer rules. These rules take not just self, but also an
additional argument -- value to be written. The resulting attribute is
write-only, and it's writes have all the properties of regular values
but they will also be passed to the writer rule at some point (which
runs inside it's own MaintainRule).

This might sound confusing, but in fact it solves a real problem and
saves quite a lot of code in many cases. For example:

class EnabledMixin(Model):
attrs(
_enabled=True,
_parent_enabled=True,
)
@compute(write_to='_enabled')
def enabled(self):
return self._parent_enabled and self._enabled


It also saves the programmer from some obscure errors, for example:

class Task1(Component):
attrs(start=1, length=2)

@compute(write_to='_end_write')
def end(self):
return self.start + self.length

@attr.writer
def _end_write(self, end):
self.start = end - self.length

t1 = Task1()

with ctrl.new_txn():
t1.end = 20
# _end_write didn't run yet, so it will see the next change too
t1.length = 10
# still didn't run -- it's a rule, so it will run later
assert t1.start == 1

assert t1.start == 10
assert t1.end == 20
assert t1.length == 10


if _end_write was not a rule, things wouldn't work out, we'd get
(t1.start, t1.end) == (18,28)


--
Best Regards,
Sergey Schetinin

http://s3bk.com/ -- S3 Backup
http://word-to-html.com/ -- Word to HTML Converter

Reply all
Reply to author
Forward
0 new messages