Code as data is the mantra. Functions and closures as data. So why not 
objects as data? What I propose is nothing new, but perhaps a new style.

Making objects from map structures is simple enough in Clojure. And easy 
enough to put functions in a map. So why not closures? A closure in a map 
is a lot like an object method, hmm?

I found clojure components to be inspirational. But as light-weight as they 
are, components are still too heavy-weight to be objects. But a simple map 
seems ideal. And with only a map instead of a record or deftype, 
composition is simplicity itself. But the key idea here comes from clojure 
components: contents of the map should be configuration parameters or 
architecture, but not state. Put state in an atom and then (optionally) put 
the atom in the map. But once an object is formed, the contents of the map 
should not change. There should be no need to update a reference to this 
map.

Below is what I am calling a Clojure Object. Like a Java object, the method 
holds both data and methods (closures). Note that, because we are using 
closures, local data can be accessed without having to be put in the map. 
For example, the file-channel variable is not accessed via the map and need 
not have been added to the map.

Bill

(ns aatree.db-file
  (:require [clojure.tools.logging :as log])
  (:import (java.nio.channels FileChannel)
           (java.nio.file OpenOption StandardOpenOption)))

(defn db-file-open
  ([file opts]
    (db-file-open (assoc opts :db-file file)))
  ([opts]
    (if (not (:db-file opts))
      (throw (Exception. "missing :db-file option")))
   (let [file (:db-file opts)
         ^FileChannel file-channel
         (FileChannel/open (.toPath file)
                           (into-array OpenOption
                                       [StandardOpenOption/CREATE
                                        StandardOpenOption/READ
                                        StandardOpenOption/WRITE]))
         opts (assoc opts :db-file-channel file-channel)
         opts (assoc opts
                :db-close
                (fn []
                  (try
                    (.close file-channel)
                    (catch Exception e
                      (log/warn e "exception on close of db-file")))
                  (dissoc opts :db-file-channel)))
         opts (assoc opts
                :db-file-empty?
                (fn []
                  (= 0 (.size file-channel))))
         opts (assoc opts
                :db-file-read
                (fn [byte-buffer position]
                  (.read file-channel byte-buffer position)))
         opts (assoc opts
                :db-file-write
                (fn [byte-buffer position]
                  (.write file-channel byte-buffer position)))
         opts (assoc opts
                :db-file-write-root
                (fn [byte-buffer position]
                  (.force file-channel true)
                  (.write file-channel byte-buffer position)
                  (.force file-channel true)))
         opts (assoc opts
                :db-file-force
                (fn []
                  (.force file-channel true)))]
     opts)))

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to