The conceptual framework for Environmental
Acquisition was
developed by Joseph Gil and
David H. Lorenz in the Faculty of
Computer Science at Technion, Israel Institute of Technology, and part
of Lorenz’s Ph.D Thesis. Acquisition was first presented at OOPSLA
‘96.
David Ascher was the first to implement a mechanism in
Python close to Acquisition, called
Subscription. Ascher
implemented a variant of the original proposal using an object metaclass
hook, and so he used a different name to avoid misunderstandings.
A much more powerful version of Acquisition in Python was
implemented by Jim Fulton. Fulton implemented a Python mix-in class
(written in C) that implements Environmental Acquisition for Python
objects.
“The idea is that one can set things up so that instances get attributes from their parents in a containment (has-a) hierarchy, not just the inheritance (is-a) hierarchy. This makes sense for things like background colors in GUI elements, for example –”
…
“It’s very cool, somewhat non-trivial to use right (it affects the way one designs massively), and requires a fairly deep brain-tweak. Still, worth knowing about when designing a new framework where containment is such an important notion. It’s one of the few “new” concepts in programming that I’ve seen in the last few years which I think has huge potential for simplifying complex designs.”
Samuel A. Falvo II:
“what Zope describes in several pages of text I can describe in a two sentences, “If the file or variable isn’t defined in the current folder, check the parent folder. If it’s not there, continue checking parent folders until you can’t anymore.” This is also true of properties as well as files.”
Evan Simpson:
“Acquisition: A feature of standard Zope objects which allows them to change their behavior automatically based on the context in which they are called. Hard to describe, but very powerful, as are…”
Jeffrey Shell:
“DTML Scripting can look quite ugly, but it’s (a) safe (which is good because DTML in Zope and even on its own can be edited through the web and you have security issues with that), and (b) very powerful depending on the namespace given it (which is very powerful in Zope due to the inherent Acquisition model).”
Chris McDonough:
“Other things that you’re going to want to know about (but that I’m wimping out on describing here because I’m frigging exhausted already) are polymorphism, encapsulation, and acquisition. Polymorphism and encapsulation are standard object-orientation terms. Acquisition is a Zope specialty, and isn’t discussed in any object orientation textbooks, but it’s really useful, and particularly mind boggling.”
Oleg Kiselyov:
“I have been using the ‘environment acquisition’ model since 1989, and found it very useful. This model is particularly beneficial in specifying a large number of various parameters and options. In my experience, a system of multi-level defaults is superior to the usual morass of command-line options or menu selections. I have implemented the environment acquisition model in C, C++, and Scheme and used it to specify parameters in complex numerical calculations and in requests for meteorological data.”
Books explaining Acquisition
Zope by Martina Brockmann, Katrin Kirchner, Sebastian Luhnsdorf, Mark Pratt:
excerpts:"…Acquisition is one of Zope’s crucial concepts…"
excerpts:"…If you’re curious about the general concept and other possible uses of acquisition, the link http://www.ccs.neu.edu/home/lorenz/papers/oopsla96/ points to a whitepaper about where it all began, by Joseph Gil and David H. Lorenz…"
excerpts:
“Acquisition is not intuitive. It takes a while to learn. But it is an effective tool and can be put to good use once its basic concepts are understood.”
Environmental Acquisition Revisited. Richard Cobbe and Matthias Felleisen. Pp. 14-25 of the Proceedings of POPL ‘05: Proceedings of the 32nd ACM SIGPLAN-SIGACT symposium on Principles of programming languages, (Long Beach, CA: 2005).
Abstract: In 1996, Gil and Lorenz proposed programming language
constructs for specifying environmental acquisition in addition
to inheritance acquisition for objects. They noticed that in many
programs, objects are arranged in containment hierarchies and need to
obtain information from their container objects. Therefore, if languages
allowed programmers to specify such relationships directly, type systems
and run-time environments could enforce the invariants that make these
programming patterns work.In this paper, we present a formal version
of environmental acquisition for class-based languages. Specifically,
we introduce an extension of the ClassicJava model with constructs for
environmental acquisition of fields and methods, a type system for the
model, a reduction semantics, and a type soundness proof. We also discuss
how to scale the model to a full-scale Java-like programming language.
Environmental Acquisition in Network Management. Mark Logan, Matthias Felleisen, and David Blank-Edelman. Pp. 175-184 of the Proceedings of LISA ‘02: Sixteenth Systems Administration Conference, (Berkeley, CA: USENIX Association, 2002).
Abstract:
Maintaining configurations in heterogeneous networks
poses complex problems. We observe that medium and large networks
exhibit many contextual relationships, and argue that modeling these
relationships explicitly simplifies configuration management. This paper
presents a declarative data specification language, called Anomaly,
that implements our ideas. Anomaly models containment relationships and
uses a data aggregation technique called environmental acquisition to
simplify system management. The interpreter for the language generates
and deploys configurations from a source code description of the network
and its hosts.
excerpts:
This talk explains how Zope’s acquisition mechanism builds and manages contexts for sharing information. In particular, it explains why the context that an object is acquired from takes precedence over the context it is acquires into.
Environmental Acquisition is being used by a popular open source application platform written in Python, called Zope. Acquisition is used extensively throughout the Zope application framework. For example, documents can acquire the contents of other documents so that entire environments can share standard information like headers, footers, various properties, etc.
The Acquisition implementation is quite stable. Little has changed in the last couple of years, except for few bug fixes. There is no longer a separate ExtensionClass distribution containing Acquisition, but they continue to maintain the Acquisition implementation, which is critical to the open-source web application platform, Zope. The latest Acquisition code can be gotten from the Zope distributions or from the Zope public CVS.
Linux RPM
Thanks to Jeff Rush, the Linux RPMs for Zope (release 1.10.3 and on) is broken out into standalone RPMs, so that ExtensionClasses and Acquisition can be installed for use with Python 1.5.1 by those who don’t want the entire Zope distribution.
Examples
Here is a very simple python example of Acquisition, proposed by Michel Pelletier. The y instance acquires the color attribute in the context of the x instance. Thus the code, will print ‘blue’. Just saying ‘y.isColor()’ would raise an AttributeError.
from ExtensionClass import Base
from Acquisition import Implicit
class X(Base):
def __init__(self, color):
self.color = color
class Y(Implicit):
def isColor(self):
print self.color
x = X('blue')
x.y = Y()
x.y.isColor()
Here is an example by Jim Fulton: the color of a widget should by default be the color of the parent widget. That way you change the color of the toplevel window, and all subwidgets get that color, except if they override it “locally”.
>>> class Window(Acquisition.Implicit):
... background = 'white'
... def __init__(self):
... self.menubar = MenuBar()
...
>>> class MenuBar(Acquisition.Implicit):
... def report(self):
... print "self.background =", self.background
...
>>> w = Window()
>>> w.menubar.report()
self.background = white
This hotfix addresses an important security issue that involves an error in the ‘aq_inContextOf’ method of objects that support Acquisition. A change to the access validation machinery made this bug begin to affect security restrictions. The bug, with the change to validation, made it possible to access Zope objects via Acquisition that a user would not otherwise have access to. This issue could allow users with enough internal knowledge of Zope to perform actions higher in the object hierarchy than they should be able to.
“Acquisition offers a twist to our name space theory. In strict DTML, the name space stack defines the context in which the DTML executes. Zope, however, provides another name space called Acquisition. These two name spaces together define the complete context of a Zope request.”
“So
far we have neglected to mention the importance of acquisition in DTML. Acquisition has two major effects with respect to DTML: objects can acquire DTML Methods, and DTML namespaces corresponding to objects can use acquisition to lookup variables. Let’s take each effect and look at the subtleties.
One of Zope’s main cool technologies is acquisition, and acquisition of DTML Methods by objects is a prime example of this power. As we saw earlier, when a DTML Method is called, its enclosing or acquiring Folder is passed as its client namespace. This means that if your DTML method refers to a variable named “title”, this variable is first looked up in the Folder’s namespace. This allows DTML Methods to act like templates, tailoring their content to the attributes of the object which acquires them.
Another effect of acquisition is felt in the variable lookup process. For example:
<!--#with Foo-->
<!--#var Bar-->
<!--#/with-->
In this DTML fragment the variable Bar is looked up in Foo. Even if Foo does not have a Bar attribute, Bar will be found in the Foo namespace if the Foo object can acquire Bar. This effect can catch you unaware if you are not careful.
“Acquisition is very useful; It’s one of the more interesting features of Zope. The fundamental purpose of acquisition is to provide data or behavior to an object based on its “location” rather than its “heritage”. Given “location” “A.B.C.D”, object “D” has access to all of the attributes of “A”, “B”, “C”, and “D”. If “D” asks for attribute “foo”, as long as exactly one of these objects has a “foo” attribute, there is no problem.
If both “B” and “C” have “foo” attributes, which one should “D” get? If “A” contains “B” contains “C” contains “D”, the search order is simple: “D”, “C”, “B”, “A”, and “D” sees “C.foo”. Unfortunately, in even slightly more complicated cases the answer can be subtle and non-intuitive even for those who understand acquisition thoroughly.
Ferengi Rules of Acquisition:
1) Once you have their property, you never give it back. 3) Never spend more for an acquisition than you have to. 6) Never allow inheritance to stand in the way of acquisition.”