[PEAK] What do you use 'offerAs' for?

Phillip J. Eby pje at telecommunity.com
Tue Sep 20 12:17:59 EDT 2005


At 11:29 AM 9/20/2005 +0000, Tiago Cogumbreiro wrote:
>Hi Philip,
>
>The last usage I did with "offerAs" was while creating a GUI
>application, the idea was to create the graphical interface with a
>bunch of subcomponents (one for the toolbar and menus, the other for a
>treeview and populating it and so on) , the "offerAs" as used to
>expose PropertyName("myapp.Window") or PropertyName("myapp.Toolbar")
>which is an obvious improvement in GUI code since you can access any
>exposed widget by simply obtaining it.

But there was only ever one "myapp.Window" or "myapp.Toolbar" at a time, right?



>One thing I didn't understand was how do you define and use your
>"dynamic variables"?

Here's a copy of the current doctest for my work-in-progress.  It's just a 
proof of concept, so the API could change quite a bit.  One of the API 
design problems I've been having is that the ideal API for use with the 
'with:' statement is much different than the best API for earlier versions 
of Python.  Anyway, it suffices to illustrate the execution model:


Dynamic Configuration with Contextual Variables
===============================================

 >>> import context


Basic Operations on Variables
-----------------------------

 >>> context.Variable()  # a context variable is a thread-local stack
<context.Variable object ...>

 >>> v = context.Variable("foo_var")  # it can have a name, for its repr()
 >>> v
foo_var

 >>> list(v.values())        # it has no values initially
[]
 >>> v.push(29)              # but you can push a value
 >>> v.get()                 # and get the current value
29
 >>> list(v.values())        # or iterate over all values
[29]
 >>> v.push(42)              # and then push more values
 >>> v.get()                 # current value is most-recently pushed
42
 >>> list(v.values())        # and values are yielded in newest-to-oldest order
[42, 29]
 >>> v.pop()                 # Popping removes a value
 >>> v.get()
29
 >>> list(v.values())
[29]
 >>> v.pop()
 >>> print v.get()           # None is the default value of an empty variable
None
 >>> v.get("nada")           # but you can specify an explicit default instead
'nada'

 >>> v.pop()                 # note that popping an empty variable is an error
Traceback (most recent call last):
   ...
TypeError: (foo_var, 'pop() without push()')


Whole-Context Operations
------------------------

 >>> c1 = context.snapshot()
 >>> c2 = context.snapshot()

 >>> c1 is c2    # snapshots without any changes between them are identical
True

 >>> foo = context.Variable()
 >>> foo.push("bar")
 >>> c3 = context.snapshot()
 >>> c1 is c3    # but once there's a change, it's a new snapshot
False
 >>> print foo.get()
bar

 >>> c4 = context.swap(c1)   # swap returns the current snapshot and 
replaces it
 >>> c4 is c3                # no changes since c3, so it's the same object
True

 >>> print foo.get()         # and our state now matches the snapshot at c1
None

 >>> c1 = context.swap(c3)   # reactivate "foo"
 >>> print foo.get()
bar
 >>> c5 = context.new()      # create a new, empty context
 >>> c6 = context.swap(c5)
 >>> c6 is c3
True
 >>> print foo.get()         # back to empty
None



Thread-Locality
---------------

Note: this test will probably need to change when the code goes to C

 >>> context.get_ident
<...function get_ident...>

 >>> old_gi = context.get_ident
 >>> context.get_ident = lambda: "foo"
 >>> q = context.Variable()
 >>> q.push(42)
 >>> context.get_ident = lambda: "bar"
 >>> q.get(99)
99
 >>> context.get_ident = lambda: "foo"
 >>> q.get(99)
42
 >>> q.pop()

 >>> context.get_ident = old_gi    # put it back to normal




More information about the PEAK mailing list