MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

Re: Verbing Properties



Ok, I realize I wasn't at all helpful before, so I'll try to critique the
proposed implementation constructively.

I'll start by noting that the described model is already workable in-DB.
I'll illustrate by imagining that I'm adding description to the MOO.

 = I add $root_class:description, as a callable verb returning "You see nothing
   special."
 = I add a user command, @describe, which adds a :description to the specified
   object which returns the specified text.
 = As there are no property accesses (at least none which can be assumed by
   the model), a user who wishes to access FOO's description has no choice but
   to call the :description verb.
 = Useful side effects of this:
   - For values which do not change frequently for children (sensible defaults,
     for example), this represents a significant database savings as clear
     properties need not be propagated (in fact, they do not exist at all!).
   - I suspect that the verb {"return \"foo\";"} runs faster than the verb
     {"return this.(verb);"}.

>The purpose of this draft is to propose a system for "turning properties into
>verbs"
>While this seems like a silly thing to do, it produces a number of benefits:
>*  Programmers get DIRECT control over who and what accesses their properties,
>   as such, it would not be hard to implement a $lock_utils-like system for
>   access priviledges.

For the case of properties which ought not be world-readable, such an approach
already exists.  Is this added overhead quick enough to be worthwhile?

>*  Properties need not return static values.  For
>   example #0.time  could return time() 

I think we want to maintain a distinction between verbs and properties.  (On
the other hand, I once coded a DB which used no properties, just for the hell
of it.)  Stylistically, I would prefer to use a verbcall for the effect you
give as an example.  I prefer thinking of properties as the place you store
data, so accessing them should return the data they store.

>*  Property access could be logged.

Ok, true.  But for the cases in which this is desired, an approach already exists.

>*  First step in the direction of multiple inheritance in the MOO.  With
>   this patch in place, the properties inheritance system will be 100% 
>   dependent on the verbs inheritance system.  This will halve the problems
>   associated with multiple inheritance.

Hsm.  I'll wait on this until later in the message.  In general, though, the
single-inheritance model is really seriously built into the MOO server code
(or so I've been told); it's probably significantly more work than you're
expecting to do it right.

>How it will be done:
>*  Inheritance will be removed, as far as properties are concerned.
>   This is accomplished as follows:
>   *  Two built-ins will be added:  
>      *  for BOTH of these, if bar is not DIRECTLY DEFINED (i.e. NOT 
>         inherited) on foo, E_PROPNF will be returned.  These verbs 
>         are wiz-only.
>      *  property_full(foo, "bar"), which will return 
>         {the value of foo.bar, {OWNER, PERMS}}.
>      *  set_property_full(foo, "bar", {quack, {OWNER, PERMS}) which will set 
>         foo.bar to quack and change the owner/perms as well.

I don't like this.  It feels klunky.  These are two builtins which don't
add real functionality.  (They both handle calls of other builtins?)

>   *  modifications to add_property(#1, "bar", quack, {OWNER, PERMS})
>      *  if #1 has a child(#2) with property #2.bar already,
>         E_INVARG is raised.
>      *  if #1 has a blank child(#2), the property is added to #1, and #2
>         remains UNAFFECTED.  Unlike LambdaCore, a property of TYPE_CLEAR is
>         NOT added to #2.

(One minor: LambdaMOO, not LambdaCore)

>*  Second, the property modification and retrieval routines will be changed 
>   such that: (Note that perm checking is handled exclusively by the DB)
>   *  'foo.bar' is replaced by 'foo:_get_bar()'
>   *  'foo.bar = quack' is replaced by 'foo:_set_bar(quack)'
>   *  property_info(foo, "bar") is replaced by 
>      foo:_getinfo_bar() (returns {OWNER, PERMS})
>   *  set_property_info(foo, "bar", {OWNER, PERMS}) is replaced by 
>      foo:_setinfo_bar({OWNER, PERMS}).

See way way above.  I'm not sure this overhead is worthwhile in-DB.

>*  Third, four verbs will be added to root class.
>   *  They will simulate the permissions checking and inheritance that the 
>      server used to perform.
>   *  #1:_get_*() will call property_full, and return the value, or an error.
>   *  #1:_set_*(quack) will call set_property_full and return quack 
>      or an error.
>   *  #1:_getinfo_*() will use property_full to return {OWNER, PERMS}.
>   *  #1:_setinfo_*({OWNER, PERMS}) will use set_property_full to set 
>      {OWNER, PERMS}.
>   *  for both _set* operations, if the property exists on the parent, but not
>      the child and the property is either +c and caller_perms() are the owner
>      of the child, or are -c and caller_perms() are the owner of the parent's
>      property, the property is added to the child and set appropriately.

Server gurus: how much extra space is needed for a property -definition- as
opposed to the space taken up by inheritance?

>*  Finally, some clean-up:
>   *  Properties(foo) returns the properties defined directly on foo, but not 
>      in its ancestry

This does not represent a change.

>   *  delete_property(foo, "bar") eliminates the foo.bar, and, if foo.bar is
>      -c, foo.descendents.bar.

If properties are not inherited, why should the properties on my children be
affected if I delete a property?

>   *  clear_property(foo, "bar") will delete foo.bar, unless none of foo's
>      ancestors define the prop, at which point E_INVARG is raised.
>   *  is_clear_property(foo, "bar") returns FALSE if the object defines the
>      property, or E_PROPNF if it is not in foo's ancestry.  If one of the 
>      usual errors is not generated, TRUE is returned.

... consistent with above specs.

>   *  chparent(foo, bar),
>      *  when parent(foo) == #-1, does absolutely nothing to the properties
>      *  when bar == #-1, delete any properties on foo which are defined
>         directly foo's ancestors from the descendants of foo then from foo
>         itself.

If properties are not inherited, etc.?

>      *  when neither are #-1, take the closest ancestor that is common to both
>         foo and bar (this is the 'greatest common ancestor').  Delete all
>         properties from the descendants of foo, then foo itself, that are 
>         defined by an ancestor, but not on the greatest common ancestor.
>      *  In all cases when bar != #-1, a consistancy check needs to be done.
>         *  If any property of foo is also defined on bar or any of its 
>            ancestors, return E_INVARG.
>         *  If any property of foo's children is also defined on bar or any of 
>            its ancestors, return E_INVARG.

If properties are not inherited, etc.?

This reminds me of an unfinished project on LambdaMOO.  I was working on a class
which "trusted" features to do various functions.  (There was a lot of granularity
in the "trust" arena.)  My goal was to make a player parent which was minimal
in functionality, but which would permit features to add "properties" (actually
entries in a data structure which acted like properties).

I'm not clear that the design here is a good one.

Seth
----------------------------------------------------------------------
Seth I. Rich - sir@po.cwru.edu
                                 There is nothing more precious than
Rabbits on walls, no problem.    a tear of true repentance.



Home | Subject Index | Thread Index