[PEAK] Trellis shared cells

Jeffrey Harris jeffrey at osafoundation.org
Tue Dec 2 14:57:08 EST 2008


Hi Phillip,

Hope your Thanksgiving was pleasant.

I'm trying to use shared cells, and I'm wondering if what I'm doing is
breaking the spirit of Trellis.

What I'd like to do is update a Component's child cell on-the-fly and
have rules that depend on the previous version of the cell update
themselves.

At first blush, this seems like it won't work, the rules depend on the
cell, not the Component.  But then I tried this:

----- Test 1 ------
>>> from peak.events import trellis
>>> class TempNoConvert(trellis.Component):
...     F = trellis.attr(32)
...     @trellis.compute
...     def C(self):
...         print "in C!"
...         return (self.F - 32)/1.8
...
>>> t = TempNoConvert()
>>> t.F
32
>>> t.C
in C!
0.0
>>> t.F = trellis.Value(77)
>>> t.C
in C!
25.0
--------------------

This test sort of makes it look like the C rule is updating itself when
the t.F cell changes to a new cell, except that setting t.F didn't
trigger C's print.

I'd assumed rules always cached their values, I'd missed the fact that
optional rules with no listeners don't make themselves listeners, and
thus don't (can't) cache their value.

----- Test 2 ------
>>> class TempNoConvert(trellis.Component):
...     F = trellis.attr(32)
...     @trellis.compute
...     def C(self):
...         print "in C!"
...         return (self.F - 32)/1.8
...     @trellis.maintain
...     def text(self):
...         return "C is: %s" % self.C
...
>>> t = TempNoConvert()
in C!
>>> t.F = trellis.Value(77)
>>> t.C
0.0
--------------------

Once you add a listener for C, swapping out t.F has no effect on t.C as
I'd originally expected.

So, I tried this:

----- Test 3 ------
>>> class TempNoConvert(trellis.Component):
...     F = trellis.attr(32)
...     @trellis.compute
...     def C(self):
...         print "in C!"
...         return (self.F - 32)/1.8
...     @trellis.maintain
...     def text(self):
...         return "C is: %s" % self.C
...     @trellis.modifier
...     def change_f(self, new_value):
...         old_cell = self.__cells__['F']
...         self.F = trellis.Value(new_value)
...         trellis.changed(old_cell)
...
>>> t = TempNoConvert()
in C!
>>> old_cell = t.__cells__['F']
>>> t.change_f(77)
in C!
>>> old_cell.value
32
>>> t.C
25.0

------------------

This works fine, but it makes me uneasy.  trellis.changed is
undocumented, and I'm not sure this will continue to work in the future.

If this *is* a reasonable way to work with shared cells, would it make
sense to make the trellis.changed call happen automatically when one
cell is switched out for another?

Sincerely,
Jeffrey



More information about the PEAK mailing list