I'm able to eval forms and strings defined at the root of a clojure file (example below). Then I extended this pattern to records and protocols.

Q: Is this idiomatic clojure? Is there a better pattern for encapsulating data/code in clojure?

Q: How would one guard against the brittleness of encapsulating api details like this in the data? As the Protocol and Record implementations are rev'd, how would one make the underlying data flexible to this (backwards compatible?)

-Todd

-----------------------------
CODE
-----------------------------

$ cat context.clj
(def dsl-form '(foo "bar from dsl-form"))
(def dsl-text "(foo \"bar from dsl-text\")")

(defn foo [t] (println "foo: " t))

(println "------------------------------------------")
(println "direct eval and load-string")
(println "------------------------------------------")

(eval dsl-form)
(load-string dsl-text)

(println "------------------------------------------")
(println "eval via a record and protocol")
(println "------------------------------------------")

; This implementation does not work, because there is an implicit 'this'
; implied in the record.
;(defprotocol TestProtocol1
;  (foo [t] "test method")
;  (process [s] "evaluate inpt") )
;
;(defrecord MyRecord1 [name]
;  TestProtocol1
;    (foo [t] (println "MyRecord...." t))
;    (process [s] (eval s)))
;
;(def r1 (MyRecord1. ["somename"]))
;  (doto r1
;    (.process dsl-form)
;    (.process dsl-text)))
;

;(def dsl-form2 '(foo this "bar from dsl-form"))
;(def dsl-text2 "(foo this \"bar from dsl-text\")")
;
;(defprotocol TestProtocol2
;  (foo [this t] "test method")
;  (process [this s] "evaluate inpt") )
;
;(defrecord MyRecord2 [name]
;  TestProtocol2
;    (foo [this t] (println "MyRecord2...." t))
;    (process [this s] (eval s)))
;
;(def r2 (MyRecord2. ["somename"]))
;
;(doto r2
; (.process dsl-form2)
; (.process dsl-text2))


(def *record* nil)

(def dsl-form3 '(foo *record* "bar from dsl-form"))
(def dsl-text3 "(foo *record* \"bar from dsl-text\")")

(defprotocol TestProtocol3
  (foo [this t] "test method")
  (process [this s] "evaluate inpt") )

(defrecord MyRecord3 [name]
  TestProtocol3
    (foo [this t] (println "MyRecord3...." t))
    (process [this s]
      (binding [*record* this]
        (eval s))))

(def r3 (MyRecord3. ["somename"]))

(doto r3
 (.process dsl-form3)
 (.process dsl-text3))


-----------------------------
OUTPUT
-----------------------------
t...@greenmachine:~/Documents/projects/clojure/lein-test/clojure-cad$ clj.sh context.clj java -server -cp /Users/todd/bin/jline/jline-0_9_5.jar:/Users/todd/bin/clojure/clojure.jar:/Users/todd/bin/clojure/clojure-contrib.jar jline.ConsoleRunner clojure.main context.clj
------------------------------------------
direct eval and load-string
------------------------------------------
foo:  bar from dsl-form
foo:  bar from dsl-text
------------------------------------------
eval via a record and protocol
------------------------------------------
Warning: protocol #'user/TestProtocol3 is overwriting function foo
MyRecord3.... bar from dsl-form

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to