~subsetpark/fugue

3cf67c49ece5d4690f430baf6668e75d4406af65 — Zach Smith 6 months ago 0ffb9b6
Do some type checking in field getter
2 files changed, 22 insertions(+), 15 deletions(-)

M fugue.janet
M test/fugue.janet
M fugue.janet => fugue.janet +21 -14
@@ 17,6 17,18 @@
    (bare-proto "Prototype" [])
    (put :_init identity)))

(defn fields
  ```
  Return all the defined fields for `obj` and its prototype
  hierarchy.
  ```
  [obj]
  (let [proto-fields ;(if (table? obj)
                        (fields (table/getproto obj))
                        @[])
        obj-fields (or (get-in obj [:_meta :fields]) @[])]
    (array ;proto-fields ;obj-fields)))

#
# defproto Forms
#


@@ 155,10 167,11 @@

(eval (new-form 'Root))


(defn- getters
  [name fields]
  [name field-list]
  (let [forms @[]]
    (loop [[field-name attrs] :in fields
    (loop [[field-name attrs] :in field-list
           :let [key-field (keyword field-name)]]
      # Allow specifying another getter name or `false`
      # for no getter


@@ 171,6 184,12 @@
          (array/push forms ~(defn ,getter-name
                               ,docstring
                               [,self]
                               (let [current-fields (,fields ,self)]
                                 (unless (,index-of ,key-field current-fields)
                                   (,errorf "type error: expected proto with field %q, got %s with fields: %q"
                                            ,key-field
                                            (in ,self :_name)
                                            current-fields)))
                               (,in ,self ,key-field)))
          (array/push forms ~(defn ,qualified-name
                               ,docstring


@@ 364,18 383,6 @@
                      __super (__parent ,method-name)]
                  ,;body))))])))

(defn fields
  ```
  Return all the defined fields for `obj` and its prototype
  hierarchy.
  ```
  [obj]
  (let [proto-fields ;(if (table? obj)
                        (fields (table/getproto obj))
                        @[])
        obj-fields (or (get-in obj [:_meta :fields]) @[])]
    (array ;proto-fields ;obj-fields)))

#
# Multimethod Helpers
#

M test/fugue.janet => test/fugue.janet +1 -1
@@ 149,7 149,7 @@
    (accessor-tests name [a-pekingese Dog Pekingese])
    (accessor-tests size [a-pekingese Pekingese])

    (is (nil? (size Dog)))
    (is (thrown? (size Dog)))
    (is (= "Fido" (name a-pekingese)))
    (is (= "Extremely Small" (size a-pekingese)))