TODO
----
Cleanup on recycling
ISSUES
------
Protocols are not robust when it comes to following--make sure no
security holes, and think about common cases of unintentionally
breaking it.
PROTOCOLS
---------
It is sometimes helpful for an object to know if another object
follows a protocol; for instance, a located object would like to make
sure that its location follows the container protocol.
Unfortunately, this is a very complicated issue in an environment
involving multiple untrusted programmers. The system described here
is not bulletproof, but should be good enough in practice.
The current system involves a couple of non-overridable root object
methods and a few methods on $sys. The methods are:
$root.follows(protocol):
Returns true if the system object trusts this object to follow
<protocol>, which is a symbol. For instance, $located could
use "if (loc.follows('container))" to ask if the system object
trusts loc to follow the container protocol.
Checking is done by doing a has_ancestor() on each object in
$sys.followers(protocol). This is not robust: the object may
change parents, and it can override non-overridable methods on
the ancestor by including other parents. Therefore, you
should use .follows() as a heuristic only, and should not rely
on it for security.
$root.is_agent(protocol);
Returns true if the system object thinks this object can act
as an agent of <protocol>, a symbol. Agents of a protocol
commonly have special permissions; for instance,
$sys.add_parent can only be called by methods on agents of
the hierarchy protocol; it checks this with
"if (!caller().is_agent('hierarchy))".
Checking is done by determining whether the current object is
in $sys.agents(protocol). This is robust.
$sys.followers(protocol):
Returns a list of objects which follow <protocol>, a symbol.
If $sys has not been instructed to trust any objects to follow
<protocol>, this method returns the empty list.
$sys.agents(protocol):
Returns a list of agents of <protocol>, a symbol. If $sys has
not been instructed to trust any agents of <protocol>, this
method returns the empty list.
$sys.trust(object, protocol, type) (wizard-only):
Instructs the system object to trust <object> to follow or be
an agent of <protocol>, according to <type>, which should be
either 'follow or 'agent.
$sys.untrust(object, protocol)
Stops trusting <object> to follow or be an agent of
<protocol>.