[Commits] (pje) Spike: rearrange schema docs' introduction so that
the cool examples come
commits at osafoundation.org
commits at osafoundation.org
Tue Feb 15 16:40:24 PST 2005
Commit by: pje
Modified files:
internal/Spike/src/spike/schema.txt 1.4 1.5
Log message:
Spike: rearrange schema docs' introduction so that the cool examples come
first. :) The docs still need lots of work, but now it should bother
people less when they just want to know what the heck the module does. :)
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/internal/Spike/src/spike/schema.txt.diff?r1=text&tr1=1.4&r2=text&tr2=1.5
Index: internal/Spike/src/spike/schema.txt
diff -u internal/Spike/src/spike/schema.txt:1.4 internal/Spike/src/spike/schema.txt:1.5
--- internal/Spike/src/spike/schema.txt:1.4 Tue Feb 15 15:41:54 2005
+++ internal/Spike/src/spike/schema.txt Tue Feb 15 16:40:23 2005
@@ -2,16 +2,123 @@
Schema Definition Support
=========================
-The ``spike.schema`` module is used to define new Spike content types and the
-relationships between them.
-
- >>> from spike import schema, events
+.. contents:: **Table of Contents**
------------
Introduction
------------
+The ``spike.schema`` module is used to define new Spike content types and the
+relationships between them. Here's a simple example::
+
+ >>> from spike import schema
+
+ >>> class Person(schema.Entity):
+ ... name = schema.One(str)
+ ... age = schema.One(int)
+ ... parents = schema.Many()
+ ... children = schema.Many(inverse=parents)
+ ... def __repr__(self): return self.name
+
+You can create instances of ``schema.Entity`` classes using keyword arguments
+to set their initial attribute values, and you can also manipulate their
+attributes normally after creation::
+
+ >>> Joe = Person(name="Joe", age=39)
+ >>> Joe
+ Joe
+ >>> Joe.age
+ 39
+ >>> del Joe.age
+ >>> Joe.age
+ Traceback (most recent call last):
+ ...
+ AttributeError: age
+
+ >>> Joe.age = 40
+
+Attributes are type-checked; you can't set them to values that don't conform
+to the type declared in the class::
+
+ >>> Joe.children = ["Sam", "Nancy"]
+ Traceback (most recent call last):
+ ...
+ TypeError: 'Sam' is not of type Person
+
+ >>> Joe.age = 1.5
+ Traceback (most recent call last):
+ ...
+ TypeError: 1.5 is not of type int
+
+If an error occurs when changing an attribute, the original value is restored::
+
+ >>> Joe.age
+ 40
+
+And bidirectional relationships are automatically maintained, so for our
+``Person`` class you don't have to change both the ``parents`` and ``children``
+attributes, just one or the other suffices::
+
+ >>> Bob = Person(name="Bob")
+ >>> Mary = Person(name="Mary")
+ >>> Joe.parents = [Bob, Mary]
+ >>> list(Bob.children)
+ [Joe]
+ >>> list(Mary.children)
+ [Joe]
+ >>> del Mary.children
+ >>> list(Joe.parents)
+ [Bob]
+ >>> Bob.children.remove(Joe)
+ >>> list(Joe.parents)
+ []
+
+Sometimes, you need to be able to define a relationship without modifying one
+or both of the types involved. For example, if someone wanted to create a
+"likes" relationship between ``Person`` objects, they could do it like this::
+
+ >>> class Likes(schema.Relationship):
+ ... likedBy = schema.Many(Person)
+ ... likes = schema.Many(Person)
+
+Then they could use the schema dynamic API to access this data without using
+attributes::
+
+ >>> Likes.likedBy.of(Joe)
+ Set([], type=Person)
+
+ >>> Likes.likes.of(Joe).add(Bob) # Joe likes Bob...
+ >>> Likes.likes.of(Joe)
+ Set([Bob], type=Person)
+
+ >>> Likes.likedBy.of(Bob) # Which means Bob is likedBy Joe
+ Set([Joe], type=Person)
+
+This works for all attribute definitions, not just externally-defined
+relationships::
+
+ >>> Person.age.of(Joe)
+ Set([40], type=int)
+
+For ease of programming, the ``of()`` method always returns an observable set,
+even if the attribute can only have one value. In any case, you can subscribe
+to receive ``models.SetChanged`` events (see ``spike.models``) whenever a set's
+membership changes::
+
+ >>> def printIt(event): print event
+ >>> Person.age.of(Joe).subscribe(printIt)
+
+ >>> Joe.age = 41
+ <Change for Set([41], type=int): removed=[40], added=[41]>
+ >>> del Joe.age
+ <Change for Set([], type=int): removed=[41], added=[]>
+ >>> Joe.age = 40
+ <Change for Set([40], type=int): removed=[], added=[40]>
+
+ >>> Joe.age = 40 # no event, because we're not really changing anything
+
+
Entities and Values
===================
@@ -128,57 +235,6 @@
needing to change Chandler's source code.
-Simple Entities
-===============
-
-Now let's define some simple entities and have a look at how they work::
-
- >>> class Person(schema.Entity):
- ... name = schema.One(str)
- ... age = schema.One(int)
- ... parents = schema.Many()
- ... children = schema.Many(inverse=parents)
- ... def __repr__(self): return self.name
-
-You can create schema instances with initial values using keyword arguments,
-and then manipulate their attributes normally::
-
- >>> Joe = Person(name="Joe", age=39)
- >>> Joe
- Joe
- >>> Joe.age
- 39
- >>> del Joe.age
- >>> Joe.age
- Traceback (most recent call last):
- ...
- AttributeError: age
-
-Attributes are type-checked::
-
- >>> Joe.age = 1.5
- Traceback (most recent call last):
- ...
- TypeError: 1.5 is not of type int
-
-And bidirectional relationships are automatically maintained::
-
- >>> Bob = Person(name="Bob")
- >>> Mary = Person(name="Mary")
- >>> Joe.parents = [Bob, Mary]
- >>> list(Bob.children)
- [Joe]
- >>> list(Mary.children)
- [Joe]
- >>> del Mary.children
- >>> list(Joe.parents)
- [Bob]
- >>> Bob.children.remove(Joe)
- >>> list(Joe.parents)
- []
-
-
-
------------
Role Objects
------------
@@ -686,15 +742,8 @@
Roles
-* Role can retrieve itself for an Entity (``aRole.of(anEntity)``)
-
-* Role classes exist for each cardinality (initially: One & Many)
-
* Roles __reduce__ as global objects (so they don't get pickled)
-* Role knows how to create a default set of the right type for its cardinality
- (and notices if it has no valid types defined)
-
* Role knows its requiredness, and other metadata (policies?)
* Role.__setattr__ doesn't allow setting unless current value is None/unset, or
More information about the Commits
mailing list