~subsetpark/fugue

daa5d839774f2a1b078ca918c92ce1ba0d3c5058 — Zach Smith 5 months ago 0587dd0
Use tuple syntax for with-slots
2 files changed, 18 insertions(+), 18 deletions(-)

M fugue.janet
M test/fugue.janet
M fugue.janet => fugue.janet +15 -15
@@ 634,17 634,15 @@
(defn- field-transformer
  [fields as proto-name]
  (fn [sym]
    (let [field-name (and (symbol? sym) (keyword (string/slice sym 1)))]
      (if (and (symbol? sym)
               (= ((string sym) 0) (chr "@")))
        (do
          (unless (index-of field-name fields)
            (errorf "Encountered field reference %q for prototype %q; expected one of: %q"
                    sym
                    proto-name
                    fields))
          ~(,as ,field-name))
        sym))))
    (if (and (tuple? sym) (= (length sym) 2) (= (sym 0) '@))
      (let [field-name (-> sym (1) (keyword))]
        (unless (index-of field-name fields)
          (errorf "Encountered field reference %q for prototype %q; expected one of: %q"
                  sym
                  proto-name
                  fields))
        ~(,as ,field-name))
      sym)))

(defn- with-slots-as
  [proto obj as body]


@@ 658,8 656,10 @@

  Injects `this` into scope as a reference to `obj`.

  Any symbols that begin with `@` are transformed into `(this <field name>)`,
  so that `@name` or its setter form `(set @name foo)` do the right thing.
  The pattern `(@ <field name>)` is transformed into `(this (keyword
  <field name>))`, if and only if `<field name>` is defined for
  `proto`, so that `(@ name)` or its setter form `(set (@ name) foo)`
  do the right thing.

  ---



@@ 669,8 669,8 @@
  repl:2:> (defproto Foo nil name {:default "Jane Doe"})
  repl:3:> (def f (new-Foo))
  repl:4:> (with-slots Foo f
             (set @name "Cosmo Kramer")
             (print @name)
             (set (@ name) "Cosmo Kramer")
             (print (@ name))
             (print (Foo? this)))
  Cosmo Kramer
  true

M test/fugue.janet => test/fugue.janet +3 -3
@@ 352,13 352,13 @@
(deftest slots-test
  (let [a-slot-haver (:new SlotHaver)]
    (fugue/with-slots SlotHaver a-slot-haver
                      (set @name "will shortz")
                      (is (= "will shortz" @name))
                      (set (@ name) "will shortz")
                      (is (= "will shortz" (@ name)))
                      (is (= "will shortz" (this :name)))
                      (is (= "will shortz" (name this))))
    (is (= "will shortz" (a-slot-haver :name)))))

(deftest slots-validation
  (is (thrown? (apply fugue/with-slots ['SlotHaver {} '@other]))))
  (is (thrown? (apply fugue/with-slots '[SlotHaver {} (@ other)]))))

(run-tests!)