FOOPReference template

Started by hartrock, August 20, 2015, 05:45:33 PM

Previous topic - Next topic

hartrock

After loading this code:

;;
;; FOOPReference template
;;

(context 'FOOPReference)

;; indices of elems in FOOP list
(constant 's_class 0 's_ref 1)
;; helpers
(define (ref-context-sym ix)
  (sym (string (context) "_" ix) MAIN))
(define (new-ref-context-sym)
  (ref-context-sym (++ foopCount))) ; foopCount for identifying FR instances
(define (new-ref-context)
  (let (ref_contextSym (new-ref-context-sym))
    (prefix (sym ref_contextSym ref_contextSym)))); without switching to new ctx
;; standard functor: each call increases foopCount
(define (FOOPReference:FOOPReference)
  (letn ((ref_context (new-ref-context)) ; increments foopCount
         (foop (cons (context) (cons ref_context (args)))))
    (set (sym (string ref_context) ref_context) foop) ; set ref context default
    ref_context))
;; accessors
(define (class)     ; FOOP Class
  (self s_class))
(define (reference) ; FOOP reference context
  (self s_ref))
;; cleaners
(define (delete-ref ctxSym)
  (delete ctxSym)  ; syms in context including foop default
  (delete ctxSym)) ; context in MAIN
(define (delete-ref-ix ix)
  (delete-ref (ref-context-sym ix)))
(define (delete-all-refs) ; robust against missing refs/foops already deleted
  (while (> foopCount 0)
    (delete-ref-ix foopCount)
    (-- foopCount)))

(context MAIN)


;;
;; How to use FOOPReference template for own FOOP
;;

(new FOOPReference 'MyFoop)
(context MyFoop)
;; some getter/setter: indices for data starting with 2
(define (g1 a) (self 2))          (define (g2 a) (self 3))
(define (s1 a) (setq (self 2) a)) (define (s2 a) (setq (self 3) a))
(context MAIN)
;;
;; a func modifying aFoop call-by-ref argument; so in effect for caller, too
(define (mod-foop-arg aFoop)
  (:s1 aFoop (append (:g1 aFoop) " -> modified by mod-foop-arg")))
; there has been the following session:

sr@free:~/newLISP/Examples$ newlisp FOOPReferences_code.lsp
newLISP v.10.6.4 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h

> (set 'foop (MyFoop "one" "two"))
MyFoop_1
> (default foop)
(MyFoop MyFoop_1 "one" "two")
> (mod-foop-arg foop) ; change foop given as arg to func by func
"one -> modified by mod-foop-arg"
> (default foop)
(MyFoop MyFoop_1 "one -> modified by mod-foop-arg" "two")
> (set 'foop (MyFoop "first" "second"))
MyFoop_2
> (default foop)
(MyFoop MyFoop_2 "first" "second")
> (default MyFoop_1) (default MyFoop_2)
(MyFoop MyFoop_1 "one -> modified by mod-foop-arg" "two")
(MyFoop MyFoop_2 "first" "second")
> (MyFoop:delete-all-refs)
0
> foop MyFoop_1 MyFoop_2 ; check all references
nil
nil
nil
> ; -> all gone

This technique can be used for multiple FOOPReference classes like MyFoop in the example; each getting its own FOOP reference namespace (e.g. FirstFOOP_1, FirstFOOP_2, ...; SecondFOOP_1, SecondFOOP_2, ...) and its own delete-* funcs (only deleting its own references).