Acquisition

Frequently Asked Questions about Acquisition

Bookmark this page as http://openu.ac.il/home/lorenz/research/acquisition/.

Environmental Acquisition

Table of Contents

Conceptual Framework

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.

Paper

Environmental Acquisition In-the-Wild

What others say about Acquisition

  • David Ascher:

“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…"

Others who made the transition to Acquisition

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:acquisition, at once the most powerful and mystical feature of Zope

excerpts: … Zope folders are also informed by notions of environmental acquisition and its powerful means of context control…

excerpts: …a powerful, but not easy to understand Zope concept: acquisition.

Presentations

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.

Component Design Patterns

Implementation in Python

Use in Zope

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.

Python

Ferengi Rules of Acquisition

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.”

David H. Lorenz
David H. Lorenz
Dept. of Mathematics and Computer Science

Senior Faculty at Open University