1clay(n)                         Clay Framework                         clay(n)
2
3
4
5______________________________________________________________________________
6

NAME

8       clay - A minimalist framework for large scale OO Projects
9

SYNOPSIS

11       package require Tcl  8.6
12
13       package require uuid
14
15       package require oo::dialect
16
17       proc clay::PROC name arglist body ?ninja ?
18
19       proc clay::_ancestors resultvar class
20
21       proc clay::ancestors ?args?
22
23       proc clay::args_to_dict ?args?
24
25       proc clay::args_to_options ?args?
26
27       proc clay::dynamic_arguments ensemble method arglist ?args?
28
29       proc clay::dynamic_wrongargs_message arglist
30
31       proc clay::is_dict d
32
33       proc clay::is_null value
34
35       proc clay::leaf ?args?
36
37       proc clay::K a b
38
39       proc clay::noop ?args?
40
41       proc clay::cleanup
42
43       proc clay::object_create objname ?class ?
44
45       proc clay::object_rename object newname
46
47       proc clay::object_destroy ?args?
48
49       proc clay::path ?args?
50
51       proc clay::putb ?map? text
52
53       proc clay::script_path
54
55       proc clay::NSNormalize qualname
56
57       proc clay::uuid_generate ?args?
58
59       proc clay::uuid::generate_tcl_machinfo
60
61       proc clay::uuid::tostring uuid
62
63       proc clay::uuid::fromstring uuid
64
65       proc clay::uuid::equal left right
66
67       proc clay::uuid cmd ?args?
68
69       proc clay::tree::sanitize dict
70
71       proc clay::tree::_sanitizeb path varname dict
72
73       proc clay::tree::storage rawpath
74
75       proc clay::tree::dictset varname ?args?
76
77       proc clay::tree::dictmerge varname ?args?
78
79       proc clay::tree::merge ?args?
80
81       proc dictargs::proc name argspec body
82
83       proc dictargs::method name argspec body
84
85       proc clay::dialect::Push class
86
87       proc clay::dialect::Peek
88
89       proc clay::dialect::Pop
90
91       proc clay::dialect::create name ?parent ?
92
93       proc clay::dialect::NSNormalize namespace qualname
94
95       proc clay::dialect::DefineThunk target ?args?
96
97       proc clay::dialect::Canonical namespace NSpace class
98
99       proc clay::dialect::Define namespace class ?args?
100
101       proc clay::dialect::Aliases namespace ?args?
102
103       proc clay::dialect::SuperClass namespace ?args?
104
105       proc clay::dynamic_methods class
106
107       proc clay::dynamic_methods_class thisclass
108
109       proc clay::define::Array name ?values ?
110
111       proc clay::define::Delegate name info
112
113       proc clay::define::constructor arglist rawbody
114
115       proc clay::define::Class_Method name arglist body
116
117       proc clay::define::class_method name arglist body
118
119       proc clay::define::clay ?args?
120
121       proc clay::define::destructor rawbody
122
123       proc clay::define::Dict name ?values ?
124
125       proc clay::define::Option name ?args?
126
127       proc clay::define::Method name argstyle argspec body
128
129       proc clay::define::Option_Class name ?args?
130
131       proc clay::define::Variable name ?default ?
132
133       proc clay::ensemble_methodbody ensemble einfo
134
135       proc clay::define::Ensemble rawmethod ?args?
136
137       proc clay::event::cancel self ?task *?
138
139       proc clay::event::generate self event ?args?
140
141       proc clay::event::nextid
142
143       proc clay::event::Notification_list self event ?stackvar ?
144
145       proc clay::event::notify rcpt sender event eventinfo
146
147       proc clay::event::process self handle script
148
149       proc clay::event::schedule self handle interval script
150
151       proc clay::event::subscribe self who event
152
153       proc clay::event::unsubscribe self ?args?
154
155       proc clay::singleton name script
156
157       method clay ancestors
158
159       method clay dump
160
161       method clay find path ?path...?
162
163       method clay get path ?path...?
164
165       method clay GET path ?path...?
166
167       method clay merge dict ?dict...?
168
169       method clay replace dictionary
170
171       method clay search path ?path...?
172
173       method clay set path ?path...? value
174
175       method clay ancestors
176
177       method clay cache path value
178
179       method clay cget field
180
181       method clay delegate ?stub? ?object?
182
183       method clay dump
184
185       method clay ensemble_map
186
187       method clay eval script
188
189       method clay evolve
190
191       method clay exists path ?path...?
192
193       method clay flush
194
195       method clay forward method object
196
197       method clay get path ?path...?
198
199       method clay leaf path ?path...?
200
201       method clay merge dict ?dict...?
202
203       method clay mixin class ?class...?
204
205       method clay mixinmap ?stub? ?classes?
206
207       method clay provenance path ?path...?
208
209       method clay replace dictionary
210
211       method clay search path valuevar isleafvar
212
213       method clay source filename
214
215       method clay set path ?path...? value
216
217       method InitializePublic
218
219______________________________________________________________________________
220

DESCRIPTION

222       Clay  introduces  a  method  ensemble  to both oo::class and oo::object
223       called clay. This ensemble handles all of the high  level  interactions
224       within the framework.  Clay stores structured data. Clan manages method
225       delegation. Clay has facilities to manage the complex interactions that
226       come about with mixins.
227
228       The central concept is that inside of every object and class (which are
229       actually objects too) is a dict called clay. What  is  stored  in  that
230       dict is left to the imagination. But because this dict is exposed via a
231       public method, we can share structured data  between  object,  classes,
232       and mixins.
233
234   STRUCTURED DATA
235       Clay  uses  a standardized set of method interactions and introspection
236       that TclOO already provides to perform on-the-fly searches.  On-the-fly
237       searches  mean  that  the data is never stale, and we avoid many of the
238       sorts of collisions that would arise when objects start mixing in other
239       classes during operation.
240
241       The  clay  methods  for  both  classes and objects have a get and a set
242       method. For objects, get will search through the local  clay  dict.  If
243       the requested leaf is not found, or the query is for a branch, the sys‐
244       tem will then begin to poll the clay methods of all of the  class  that
245       implements  the  object, all of that classes’ ancestors, as well as all
246       of the classes that have been mixed into this object, and all of  their
247       ancestors.
248
249       Intended  branches  on  a tree end with a directory slash (/). Intended
250       leaves are left unadorned. This is a guide for the tool that builds the
251       search results to know what parts of a dict are intended to be branches
252       and which are intended to be leaves.  For simple cases, branch  marking
253       can be ignored:
254
255
256              ::oo::class create ::foo { }
257              ::foo clay set property/ color blue
258              ::foo clay set property/ shape round
259
260              set A [::foo new]
261              $A clay get property/
262              {color blue shape round}
263
264              $A clay set property/ shape square
265              $A clay get property/
266              {color blue shape square}
267
268
269       But  when  you  start  storing blocks of text, guessing what field is a
270       dict and what isn’t gets messy:
271
272
273              ::foo clay set description {A generic thing of designated color and shape}
274
275              $A clay get description
276              {A generic thing of designated color and shape}
277
278              Without a convention for discerning branches for leaves what should have been a value can be accidentally parsed as a dictionary, and merged with all of the other values that were never intended to be merge. Here is an example of it all going wrong:
279              ::oo::class create ::foo { }
280              # Add description as a leaf
281              ::foo clay set description  {A generic thing of designated color and shape}
282              # Add description as a branch
283              ::foo clay set description/  {A generic thing of designated color and shape}
284
285              ::oo::class create ::bar {
286                superclass foo
287              }
288              # Add description as a leaf
289              ::bar clay set description  {A drinking establishment of designated color and shape and size}
290              # Add description as a branch
291              ::bar clay set description/  {A drinking establishment of designated color and shape and size}
292
293              set B [::bar new]
294              # As a leaf we get the value verbatim from he nearest ancestor
295              $B clay get description
296                {A drinking establishment of designated color and shape and size}
297              # As a branch we get a recursive merge
298              $B clay get description/
299              {A drinking establishment of designated color and size thing of}
300
301
302   CLAY DIALECT
303       Clay is built using the oo::dialect module from Tcllib. oo::dialect al‐
304       lows you to either add keywords directly to clay, or to create your own
305       metaclass and keyword set using Clay as a foundation.  For  details  on
306       the keywords and what they do, consult the functions in the ::clay::de‐
307       fine namespace.
308
309   METHOD DELEGATION
310       Method Delegation It is sometimes useful to  have  an  external  object
311       that can be invoked as if it were a method of the object. Clay provides
312       a delegate ensemble method to perform that delegation, as well  as  in‐
313       trospect  which  methods  are  delegated  in that manner. All delegated
314       methods are marked with html-like tag markings (< >) around them.
315
316
317              ::clay::define counter {
318                Variable counter 0
319                method incr {{howmuch 1}} {
320                  my variable counter
321                  incr counter $howmuch
322                }
323                method value {} {
324                  my variable counter
325                  return $counter
326                }
327                method reset {} {
328                  my variable counter
329                  set counter 0
330                }
331              }
332              ::clay::define example {
333                variable buffer
334                constructor {} {
335                  # Build a counter object
336                  set obj [namespace current]::counter
337                  ::counter create $obj
338                  # Delegate the counter
339                  my delegate <counter> $obj
340                }
341                method line {text} {
342                  my <counter> incr
343                  append buffer $text
344                }
345              }
346
347              set A [example new]
348              $A line {Who’s line is it anyway?}
349              $A <counter> value
350              1
351
352

COMMANDS

354       proc clay::PROC name arglist body ?ninja ?
355              Because many features in this package may be added  as  commands
356              to  future tcl cores, or be provided in binary form by packages,
357              I need a declaritive way of saying Create this command if  there
358              isn't one already.  The ninja argument is a script to execute if
359              the command is created by this mechanism.
360
361       proc clay::_ancestors resultvar class
362
363       proc clay::ancestors ?args?
364
365       proc clay::args_to_dict ?args?
366
367       proc clay::args_to_options ?args?
368
369       proc clay::dynamic_arguments ensemble method arglist ?args?
370
371       proc clay::dynamic_wrongargs_message arglist
372
373       proc clay::is_dict d
374
375       proc clay::is_null value
376
377       proc clay::leaf ?args?
378
379       proc clay::K a b
380
381       proc clay::noop ?args?
382              Perform a noop. Useful in prototyping for commenting out  blocks
383              of  code  without  actually  having to comment them out. It also
384              makes a handy default for method delegation if  a  delegate  has
385              not been assigned yet.
386
387       proc clay::cleanup
388              Process the queue of objects to be destroyed
389
390       proc clay::object_create objname ?class ?
391
392       proc clay::object_rename object newname
393
394       proc clay::object_destroy ?args?
395              Mark an objects for destruction on the next cleanup
396
397       proc clay::path ?args?
398
399       proc clay::putb ?map? text
400              Append  a  line of text to a variable. Optionally apply a string
401              mapping.
402
403       proc clay::script_path
404
405       proc clay::NSNormalize qualname
406
407       proc clay::uuid_generate ?args?
408
409       proc clay::uuid::generate_tcl_machinfo
410
411       proc clay::uuid::tostring uuid
412
413       proc clay::uuid::fromstring uuid
414              Convert a string representation of a uuid into its  binary  for‐
415              mat.
416
417       proc clay::uuid::equal left right
418              Compare two uuids for equality.
419
420       proc clay::uuid cmd ?args?
421              uuid generate -> string rep of a new uuid uuid equal uuid1 uuid2
422
423       proc clay::tree::sanitize dict
424              Output   a   dictionary   removing   any   .  entries  added  by
425              clay::tree::merge
426
427       proc clay::tree::_sanitizeb path varname dict
428              Helper function for ::clay::tree::sanitize  Formats  the  string
429              representation  for a dictionary element within a human readable
430              stream of lines, and determines if it needs to call itself  with
431              further indentation to express a sub-branch
432
433       proc clay::tree::storage rawpath
434              Return the path as a storage path for clay::tree with all branch
435              terminators removed.  This command will also break arguments  up
436              if they contain /.
437
438              Example:
439
440               > clay::tree::storage {foo bar baz bang}
441               foo bar baz bang
442               > clay::tree::storage {foo bar baz bang/}
443               foo bar baz bang
444               > clay::tree::storage {foo bar baz bang:}
445               foo bar baz bang:
446               > clay::tree::storage {foo/bar/baz bang:}
447               foo bar baz bang:
448               > clay::tree::storage {foo/bar/baz/bang}
449               foo bar baz bang
450
451
452
453
454       proc clay::tree::dictset varname ?args?
455              Set an element with a recursive dictionary, marking all branches
456              on the way down to the final element.  If the value does not ex‐
457              ists  in  the  nested  dictionary  it is added as a leaf. If the
458              value already exists as a branch the value given  is  merged  if
459              the  value is a valid dict. If the incoming value is not a valid
460              dict, the value overrides the value stored,  and  the  value  is
461              treated as a leaf from then on.
462
463              Example:
464
465               > set r {}
466               > ::clay::tree::dictset r option color default Green
467               . {} option {. {} color {. {} default Green}}
468               > ::clay::tree::dictset r option {Something not dictlike}
469               . {} option {Something not dictlike}
470               # Note that if the value is not a dict, and you try to force it to be
471               # an error with be thrown on the merge
472               > ::clay::tree::dictset r option color default Blue
473               missing value to go with key
474
475
476
477
478       proc clay::tree::dictmerge varname ?args?
479              A recursive form of dict merge, intended for modifying variables
480              in place.
481
482              Example:
483
484               > set mydict {sub/ {sub/ {description {a block of text}}}}
485               > ::clay::tree::dictmerge mydict {sub/ {sub/ {field {another block of text}}}}]
486               > clay::tree::print $mydict
487               sub/ {
488                 sub/ {
489                   description {a block of text}
490                   field {another block of text}
491                 }
492               }
493
494
495
496
497       proc clay::tree::merge ?args?
498              A recursive form of dict merge
499
500              A routine to recursively dig through  dicts  and  merge  adapted
501              from http://stevehavelka.com/tcl-dict-operation-nested-merge/
502
503              Example:
504
505               > set mydict {sub/ {sub/ {description {a block of text}}}}
506               > set odict [clay::tree::merge $mydict {sub/ {sub/ {field {another block of text}}}}]
507               > clay::tree::print $odict
508               sub/ {
509                 sub/ {
510                   description {a block of text}
511                   field {another block of text}
512                 }
513               }
514
515
516
517
518       proc dictargs::proc name argspec body
519              Named Procedures as new command
520
521       proc dictargs::method name argspec body
522
523       proc clay::dialect::Push class
524
525       proc clay::dialect::Peek
526
527       proc clay::dialect::Pop
528
529       proc clay::dialect::create name ?parent ?
530              This  proc will generate a namespace, a "mother of all classes",
531              and a rudimentary set of policies for this dialect.
532
533       proc clay::dialect::NSNormalize namespace qualname
534              Support commands; not intended to be called directly.
535
536       proc clay::dialect::DefineThunk target ?args?
537
538       proc clay::dialect::Canonical namespace NSpace class
539
540       proc clay::dialect::Define namespace class ?args?
541              Implementation of the languages' define command
542
543       proc clay::dialect::Aliases namespace ?args?
544
545       proc clay::dialect::SuperClass namespace ?args?
546
547       proc clay::dynamic_methods class
548
549       proc clay::dynamic_methods_class thisclass
550
551       proc clay::define::Array name ?values ?
552              New OO Keywords for clay
553
554       proc clay::define::Delegate name info
555              An annotation that objects of this class interact with delegated
556              methods.  The annotation is intended to be a dictionary, and the
557              only reserved key is description, a human readable description.
558
559       proc clay::define::constructor arglist rawbody
560
561       proc clay::define::Class_Method name arglist body
562              Specify the a method for the class object itself, instead of for
563              objects of the class
564
565       proc clay::define::class_method name arglist body
566              And alias to the new Class_Method keyword
567
568       proc clay::define::clay ?args?
569
570       proc clay::define::destructor rawbody
571
572       proc clay::define::Dict name ?values ?
573
574       proc clay::define::Option name ?args?
575              Define an option for the class
576
577       proc clay::define::Method name argstyle argspec body
578
579       proc clay::define::Option_Class name ?args?
580              Define a class of options All field / value pairs will be be in‐
581              herited by an option that specify name as it class field.
582
583       proc clay::define::Variable name ?default ?
584              This keyword can also be expressed:
585
586              property variable NAME {default DEFAULT}
587
588       Variables registered in the variable property are also initialized  (if
589       missing) when the object changes class via the morph method.
590
591       proc clay::ensemble_methodbody ensemble einfo
592              Produce  the body of an ensemble's public dispatch method ensem‐
593              ble is the name of the the ensemble.  einfo is a  dictionary  of
594              methods  for the ensemble, and each value is a script to execute
595              on dispatch
596
597              Example:
598
599               ::clay::ensemble_methodbody foo {
600                 bar {tailcall my Foo_bar {*}$args}
601                 baz {tailcall my Foo_baz {*}$args}
602                 clock {return [clock seconds]}
603                 default {puts "You gave me $method"}
604               }
605
606
607
608
609       proc clay::define::Ensemble rawmethod ?args?
610
611       proc clay::event::cancel self ?task *?
612              Cancel a scheduled event
613
614       proc clay::event::generate self event ?args?
615              Generate an event Adds a subscription mechanism for  objects  to
616              see who has recieved this event and prevent spamming or infinite
617              recursion
618
619       proc clay::event::nextid
620
621       proc clay::event::Notification_list self event ?stackvar ?
622              Called recursively to produce a list of who  recieves  notifica‐
623              tions
624
625       proc clay::event::notify rcpt sender event eventinfo
626              Final delivery to intended recipient object
627
628       proc clay::event::process self handle script
629              Evaluate an event script in the global namespace
630
631       proc clay::event::schedule self handle interval script
632              Schedule an event to occur later
633
634       proc clay::event::subscribe self who event
635              Subscribe an object to an event pattern
636
637       proc clay::event::unsubscribe self ?args?
638              Unsubscribe an object from an event pattern
639
640       proc clay::singleton name script
641              An object which is intended to be it's own class.
642

CLASSES

644   CLASS  CLAY::CLASS
645       Methods
646
647       method clay ancestors
648              Return this class and all ancestors in search order.
649
650       method clay dump
651              Return a complete dump of this object's clay data, but only this
652              object's clay data.
653
654       method clay find path ?path...?
655              Pull a chunk of data from the clay system. If the  last  element
656              of  path is a branch, returns a recursive merge of all data from
657              this object and it's constituent classes of  the  data  in  that
658              branch.  If the last element is a leaf, search this object for a
659              matching leaf, or search all  constituent classes for a matching
660              leaf  and  return  the first value found.  If no value is found,
661              returns an empty string.  If a branch is returned the topmost  .
662              entry is omitted.
663
664       method clay get path ?path...?
665              Pull  a chunk of data from the class's clay system.  If no value
666              is found, returns an empty string.  If a branch is returned  the
667              topmost . entry is omitted.
668
669       method clay GET path ?path...?
670              Pull  a chunk of data from the class's clay system.  If no value
671              is found, returns an empty string.
672
673       method clay merge dict ?dict...?
674              Recursively merge the dictionaries given into the object's local
675              clay storage.
676
677       method clay replace dictionary
678              Replace  the contents of the internal clay storage with the dic‐
679              tionary given.
680
681       method clay search path ?path...?
682              Return the first matching value for  the  path  in  either  this
683              class's clay data or one of its ancestors
684
685       method clay set path ?path...? value
686              Merge  the  conents  of  value with the object's clay storage at
687              path.
688
689   CLASS  CLAY::OBJECT
690       clay::object This class is inherited by all classes that have options.
691
692       Methods
693
694       method clay ancestors
695              Return the class this object belongs to, all classes mixed  into
696              this object, and all ancestors of those classes in search order.
697
698       method clay cache path value
699              Store  VALUE  in such a way that request in SEARCH for PATH will
700              always return it until the cache is flushed
701
702       method clay cget field
703              Pull a value from either the object's clay structure or  one  of
704              its  constituent classes that matches the field name.  The order
705              of search us:
706
707              1. The as a value in local dict variable config
708
709              2. The as a value in local dict variable clay
710
711              3. As a leaf in any ancestor as a root of the clay tree
712
713              4. As a leaf in any ancestor as const field
714
715              5. As a leaf in any ancestor as option field default
716
717       method clay delegate ?stub? ?object?
718              Introspect or control method delegation. With no arguments,  the
719              method  will  return a key/value list of stubs and objects. With
720              just the stub argument, the method will return  the  object  (if
721              any)  attached  to the stub. With a stub and an object this com‐
722              mand will forward all calls to the method stub to the object.
723
724       method clay dump
725              Return a complete dump of this object's clay data,  as  well  as
726              the data from all constituent classes recursively blended in.
727
728       method clay ensemble_map
729              Return a dictionary describing the method ensembles to be assem‐
730              bled for this object
731
732       method clay eval script
733              Evaluated a script in the namespace of this object
734
735       method clay evolve
736              Trigger the InitializePublic private method
737
738       method clay exists path ?path...?
739              Returns 1 if path exists in either the object's clay data.  Val‐
740              ues  greater  than one indicate the element exists in one of the
741              object's constituent classes. A value of zero indicates the path
742              could not be found.
743
744       method clay flush
745              Wipe any caches built by the clay implementation
746
747       method clay forward method object
748              A convenience wrapper for
749
750              oo::objdefine [self] forward {*}$args
751
752       method clay get path ?path...?
753              Pull  a  chunk of data from the clay system. If the last element
754              of path is a branch (ends in a slash  /),  returns  a  recursive
755              merge  of all data from this object and it's constituent classes
756              of the data in that branch.  If the  last  element  is  a  leaf,
757              search  this  object  for  a  matching leaf, or search all  con‐
758              stituent classes for a matching leaf and return the first  value
759              found.  If no value is found, returns an empty string.
760
761       method clay leaf path ?path...?
762              A modified get which is tailored to pull only leaf elements
763
764       method clay merge dict ?dict...?
765              Recursively merge the dictionaries given into the object's local
766              clay storage.
767
768       method clay mixin class ?class...?
769              Perform [oo::objdefine [self] mixin] on this object, with a  few
770              additional  rules:  Prior  to the call, for any class was previ‐
771              ously mixed in, but not in the new result,  execute  the  script
772              registered  to  mixin/  unmap-script  (if  given.)   For all new
773              classes, that were not present prior to this call, after the na‐
774              tive  TclOO  mixin  is invoked, execute the script registered to
775              mixin/ map-script (if given.)  Fall all  classes  that  are  now
776              present  and “mixed in”, execute the script registered to mixin/
777              react-script (if given.)
778
779       method clay mixinmap ?stub? ?classes?
780              With no arguments returns the map of  stubs  and  classes  mixed
781              into  the  current  object. When only stub is given, returns the
782              classes mixed in on that stub. When stub  and  classlist  given,
783              replace  the  classes  currently  on  that  stub  with the given
784              classes and invoke clay mixin on the  new  matrix  of  mixed  in
785              classes.
786
787       method clay provenance path ?path...?
788              Return either self if that path exists in the current object, or
789              return the first class (if any) along the clay search path which
790              contains that element.
791
792       method clay replace dictionary
793              Replace  the contents of the internal clay storage with the dic‐
794              tionary given.
795
796       method clay search path valuevar isleafvar
797              Return true, and set valuevar to the value and isleafar to  true
798              for false if PATH was found in the cache.
799
800       method clay source filename
801              Source the given filename within the object's namespace
802
803       method clay set path ?path...? value
804              Merge  the  conents  of  value with the object's clay storage at
805              path.
806
807       method InitializePublic
808              Instantiate variables. Called on object creation and during clay
809              mixin.
810

AUTHORS

812       Sean Woods mailto:<yoda@etoyoc.com>
813

BUGS, IDEAS, FEEDBACK

815       This  document,  and the package it describes, will undoubtedly contain
816       bugs and other problems.  Please report such in the category oo of  the
817       Tcllib  Trackers  [http://core.tcl.tk/tcllib/reportlist].   Please also
818       report any ideas for enhancements  you  may  have  for  either  package
819       and/or documentation.
820
821       When proposing code changes, please provide unified diffs, i.e the out‐
822       put of diff -u.
823
824       Note further that  attachments  are  strongly  preferred  over  inlined
825       patches.  Attachments  can  be  made  by  going to the Edit form of the
826       ticket immediately after its creation, and  then  using  the  left-most
827       button in the secondary navigation bar.
828

KEYWORDS

830       TclOO, oo
831

CATEGORY

833       Programming tools
834
836       Copyright (c) 2018 Sean Woods <yoda@etoyoc.com>
837
838
839
840
841tcllib                               0.8.6                             clay(n)
Impressum