[Checkins] SVN: martian/trunk/src/martian/core.txt Cleaning up some redundancies with README.txt and slight updates.

Martijn Faassen faassen at infrae.com
Fri Jun 6 11:01:46 EDT 2008


Log message for revision 87197:
  Cleaning up some redundancies with README.txt and slight updates.
  

Changed:
  U   martian/trunk/src/martian/core.txt

-=-
Modified: martian/trunk/src/martian/core.txt
===================================================================
--- martian/trunk/src/martian/core.txt	2008-06-06 14:54:51 UTC (rev 87196)
+++ martian/trunk/src/martian/core.txt	2008-06-06 15:01:46 UTC (rev 87197)
@@ -1,61 +1,12 @@
-Martian
-=======
+Martian core
+============
 
-"There was so much to grok, so little to grok from." -- Stranger in a
-Strange Land, by Robert A. Heinlein
+A simple framework
+------------------
 
-Martian provides infrastructure for declarative configuration of
-Python code. Martian is especially useful for the construction of
-frameworks that need to provide a flexible plugin
-infrastructure. Martian doesn't actually provide any infrastructure
-for plugin registries and such. Many frameworks have their own, and if
-you need a generic one, you might want to consider
-``zope.component``. Martian just allows you to make the registration
-of such plugins less verbose. 
+Let's look at a very simple framework where files are handled by their
+extensions::
 
-You can see Martian as doing something that you can also solve with
-metaclasses, with the following advantages:
-
-* the developer of the framework doesn't have to write a lot of ad-hoc
-  metaclasses anymore; instead we offer an infrastructure to make life
-  easier.
-
-* configuration doesn't need to happen at import time, but can happen at
-  program startup time. This also makes configuration more tractable for
-  a developer.
-
-* we don't bother the developer that *uses* the framework with the
-  surprising behavior that metaclasses sometimes bring. The classes
-  the user has to deal with are normal classes.
-
-Why is this package named ``martian``? In the novel "Stranger in a
-Strange Land", the verb *grok* is introduced:
-
-  Grok means to understand so thoroughly that the observer becomes a
-  part of the observed -- to merge, blend, intermarry, lose identity
-  in group experience.
-
-In the context of this package, "grokking" stands for the process of
-deducing declarative configuration actions from Python code. In the
-novel, grokking is originally a concept that comes from the planet
-Mars. Martians *grok*. Since this package helps you grok code, it's
-called Martian.
-
-The ``martian`` package is a spin-off from the `Grok project`_, in the
-context of which this codebase was first developed. While Grok uses
-it, the code is completely independent of Grok.
-
-.. _`Grok project`: http://grok.zope.org
-
-Motivation
-----------
-
-"Deducing declarative configuration actions from Python code" - that
-sounds very abstract. What does it actually mean? In order to explain
-this, let's first look at an example of a simple framework that can be
-*configured* with plugins. We will define a framework for handling
-files based on their extensions::
-
   >>> class filehandler(FakeModule):
   ...   import os
   ...
@@ -70,15 +21,6 @@
   ...   def handle(filepath):
   ...      name, ext = os.path.splitext(filepath)
   ...      return extension_handlers[ext](filepath)
-
-Since normally we cannot create modules in a doctest, we have emulated
-the ``filehandler`` Python module using the ``FakeModule``
-class. Whenever you see ``FakeModule`` subclasses, imagine you're
-looking at a module definition in a ``.py`` file. Now that we have
-defined a module ``filehandler``, we also need to be able to import
-it. To do so we can use a a fake import statement that lets us do
-this::
-
   >>> filehandler = fake_import(filehandler)
 
 Now let's try the ``handle`` function for a few file types::
@@ -97,9 +39,7 @@
   KeyError: '.png'
 
 We now want to plug into this filehandler framework and provide a
-handler for ``.png`` files. Since we are writing a plugin, we cannot
-change the ``filehandler`` module directly. Let's write an extension
-module instead::
+handler for ``.png`` files::
 
   >>> class pnghandler(FakeModule):
   ...    def handle_png(filepath):
@@ -115,36 +55,11 @@
   >>> filehandler.handle('image.png')
   'PNG file'
 
-The action of registering something into a central registry is also
-called *configuration*. Larger frameworks often offer a lot of points
-where you can configure them: ways to combine its own components with
-components you provide yourself to build a larger application.
-
-Above we plug into our ``extension_handler`` registry using Python
-code. Using separate code to manually hook components into registries
-can get rather cumbersome - each time you write an extension, you also
-need to remember you need to register it. It also poses a maintenance
-risk. It is tempting to start doing fancy things in Python code such
-as conditional configuration, making the configuration state of a
-program hard to understand. Another problem is that doing
-configuration at import time can also lead to unwanted side effects
-during import and ordering problems. It can also make code harder to
-test.
-
-Martian provides a framework that allows configuration to be expressed
-in declarative Python code. These declarations can often be deduced
-from the structure of the code itself. The idea is to make these
-declarations so minimal and easy to read that even extensive
-configuration does not overly burden the programmers working with the
-code. Configuration actions are executed during a separate phase
-("grok time"), not at import time, which makes it easier to reason
-about and easier to test.
-
 Grokkers that grok
 ------------------
 
-In this section we define the concept of a ``Grokker``. A ``Grokker``
-is an object that can *grok* objects - execute configuration actions
+Let's write a grokker that can grok the file types. A ``Grokker`` is
+an object that can *grok* objects - execute configuration actions
 pertaining to the grokked object, such as registering it with some
 central registry. Different kinds of grokkers can grok different types
 of objects (instances, classes, functions).
@@ -493,7 +408,7 @@
   <Animal snake>
 
 Note that we can supply a different default value for the directive
-default when binding the directive to the grokker:
+default::
 
   >>> class AnimalGrokker(AnimalGrokker):
   ...   martian.directive(animal.name, default='generic animal')



More information about the Checkins mailing list