M README.md => README.md +16 -12
@@ 112,7 112,7 @@ specific prototype for this key, then `fugue/allocate` will put `value`
at `key` in the appropriate prototype, and it will be inherited by
all descendents of that prototype.
-[4]: fugue.janet#L263
+[4]: fugue.janet#L272
## declare-open-multi
@@ 128,7 128,7 @@ Extending an open multimethod (see `extend-multi`) from any other
environment makes the case extension available wherever the
multimethod has been imported.
-[5]: fugue.janet#L584
+[5]: fugue.janet#L593
## defgeneric
@@ 143,7 143,7 @@ first argument has a method corresponding to the name of the
function, call that object 's method with the arguments. Otherwise,
evaluate `body`.
-[6]: fugue.janet#L297
+[6]: fugue.janet#L306
## defmethod
@@ 161,7 161,7 @@ Defines a few symbols for reference in the body of the method.
`__parent` - Bound to the parent of `proto`.
`__super` - Bound to the method at `name` within `__parent`.
-[7]: fugue.janet#L308
+[7]: fugue.janet#L317
## defmulti
@@ 233,7 233,7 @@ repl:12:> (cat "hello" 100)
"hello #100"
```
-[8]: fugue.janet#L508
+[8]: fugue.janet#L517
## defproto
@@ 277,7 277,11 @@ field (by default, has the same name as the field). Specify `false`
to prevent a getter from being defined.
`defproto` will define a getter function for each of the defined
-fields, unless `:getter` is false.
+fields, unless `:getter` is false. It will also define a "qualified"
+getter function, where the getter-name is prepended by the name of
+the prototype. This can be used to provide a greater degree of
+"type-safety", as the qualified getter won 't be defined if that
+prototype doesn 't have that field.
`defproto` will also create a `:new` method in the created
prototype. This will take as positional arguments all of the fields
@@ 305,7 309,7 @@ repl:47:> (speak (:new Pekingese))
"My name is Fido and I am Extremely Small"
```
-[9]: fugue.janet#L168
+[9]: fugue.janet#L173
## extend-multi
@@ 323,7 327,7 @@ See that function's documentation for full usage reference.
Whenever a case is added to `multi`, that case is available
wherever the multimethod is imported.
-[10]: fugue.janet#L600
+[10]: fugue.janet#L609
## fields
@@ 336,7 340,7 @@ wherever the multimethod is imported.
Return all the defined fields for `obj` and its prototype
hierarchy.
-[11]: fugue.janet#L335
+[11]: fugue.janet#L344
## get-type-or-proto
@@ 349,7 353,7 @@ hierarchy.
Return the prototype of `obj`, if it has one, otherwise the keyword
output of `type`.
-[12]: fugue.janet#L347
+[12]: fugue.janet#L356
## multimethod-types-match?
@@ 363,7 367,7 @@ Check to see if the types `args` match the sequence `arg-types`,
according to multimethod rules (ie, following prototype membership
and using `:_` as a fallback)
-[13]: fugue.janet#L436
+[13]: fugue.janet#L445
## prototype?
@@ 375,5 379,5 @@ and using `:_` as a fallback)
Is `obj` the result of a `defproto ` call?
-[14]: fugue.janet#L256
+[14]: fugue.janet#L265
M fugue.janet => fugue.janet +21 -12
@@ 118,17 118,22 @@
(defn- getters
[name fields]
- (seq [[field-name attrs] :in fields
- :let [key-field (keyword field-name)]]
- # Allow specifying another getter name or `false`
- # for no getter
- (when-let [docstring (string "Get " field-name " from a " name)
- getter-name (match attrs
- {:getter getter} getter
- _ field-name)]
- (with-syms [self]
- ~(defn ,getter-name ,docstring [,self]
- (in ,self ,key-field))))))
+ (let [forms @[]]
+ (loop [[field-name attrs] :in fields
+ :let [key-field (keyword field-name)]]
+ # Allow specifying another getter name or `false`
+ # for no getter
+ (when-let [docstring (string "Get " field-name " from a " name)
+ getter-name (match attrs
+ {:getter getter} getter
+ _ field-name)
+ qualified-name (symbol name "/" getter-name) ]
+ (with-syms [self]
+ (array/push forms ~(defn ,getter-name ,docstring [,self]
+ (in ,self ,key-field)))
+ (array/push forms ~(defn ,qualified-name ,docstring [,self]
+ (in ,self ,key-field))))))
+ forms))
(defn- pred-name [name] (symbol name "?"))
@@ 201,7 206,11 @@
to prevent a getter from being defined.
`defproto` will define a getter function for each of the defined
- fields, unless `:getter` is false.
+ fields, unless `:getter` is false. It will also define a "qualified"
+ getter function, where the getter-name is prepended by the name of
+ the prototype. This can be used to provide a greater degree of
+ "type-safety", as the qualified getter won 't be defined if that
+ prototype doesn 't have that field.
`defproto` will also create a `:new` method in the created
prototype. This will take as positional arguments all of the fields
M test/fugue.janet => test/fugue.janet +2 -1
@@ 162,7 162,8 @@
(deftest getter
(let [a-form (:new Form :unique-field :echo)]
(is (nil? (dyn 'unique-field)))
- (is (= :echo (get-unique-field a-form)))))
+ (is (= :echo (get-unique-field a-form)))
+ (is (= :echo (Form/get-unique-field a-form)))))
(fugue/defproto Form2 () second-unique-field {:getter false})