Code Monkey home page Code Monkey logo

defrecord-wrapper's Introduction

image

defrecord-wrapper

This library lets you apply middleware to protocol implementations of clojure.core/defrecord in the same way as AOP does.

As wikipedia defines AOP:

In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. AOP forms a basis for aspect-oriented software development.
...
Logging exemplifies a crosscutting concern because a logging strategy necessarily affects every logged part of the system. Logging thereby crosscuts all logged classes and methods....

Common and practical scenario
Working with juxt/modular or directly stuartsierra/component enforces you to work with defrecords (or simply maps). Using this defrecord-wrapper dependency you can totally or partially intercept your protocols functions

Releases and Dependency Information

[tangrammer/defrecord-wrapper "0.1.6"]
:dependencies [[org.clojure/clojure "1.6.0"]]

Usage

(ns your-ns
  (:require [defrecord-wrapper.aop :as aop]
            [defrecord-wrapper.reflect :as r])
  (:import [defrecord_wrapper.aop SimpleWrapper]))

;; here your protocol, defrecord definitions and defrecord instance

(defprotocol Welcome
  (greetings [e] )
  (say-bye [e a b])
  )

(defrecord Example []
  Welcome
  (greetings [this] "my example greeting!")
  (say-bye [this a b] (str "saying good bye from " a " to " b)))

(def my-example-instance (Example.))

;; here your fn middleware to apply

(defn logging-access-protocol
  [*fn* this & args]
  (println ">> LOGGING-ACCESS " [this args])
  (println ">>"(meta *fn*))
  (apply *fn* (conj args this)))


;; here extending SimpleWrapper with your defrecord instance functions protocols

(aop/add-extends SimpleWrapper (r/get-specific-supers my-example-instance) logging-access-protocol)

;; here wrapping your defrecord instance with SimpleWrapper 

(def my-wrapped-example (SimpleWraper. my-example-instance))


;; and ... invoking wrapper

(println (greetings my-wrapped-example))

;;=> >> LOGGING-ACCESS  [#yourapp.your_ns.Example{} nil]
;;=> >> {:function-args [e], :wrapper #defrecord_wrapper.aop.SimpleWrapper{:wrapped-record #yourapp.your_ns.Example{}}, :function-name greetings}
;;=> my example greeting!


(println (say-bye my-wrapped-example "clojure" "java"))
;;=> >> LOGGING-ACCESS  [#yourapp.your_ns.Example{} (clojure java)]
;;=> >> {:function-args [e a b], :wrapper #defrecord_wrapper.aop.SimpleWrapper{:wrapped-record #yourapp.your_ns.Example{}}, :function-name say-bye}

Matchers available in tangrammer/defrecord-wrapper

Due that milesian/aop actually uses tangrammer/defrecord-wrapper, there are a few special matchers for free that you can be intereseted on using:

  • nil value that returns nil
  • fn value that returns itself, (it's a shortcut to apply your-fn-middleware for all fns protocol)
  • defrecord-wrapper.aop/SimpleProtocolMatcher that returns your-fn-middleware when the protocol of the fn invoked matchs with any of the the protocols provided

SimpleProtocolMatcher implementation

Instead of plain functions or your own implementations of Matcher protocol, you can also use the SimpleProtocolMatcher as follows

(aop/add-extends SimpleWrapper 
    (r/get-specific-supers my-example-instance) 
    (aop/new-simple-protocol-matcher 
        :protocols [Welcome] 
        :fn logging-access-invocation))

For more detailed matching there is also a bidi-wrapper-matcher, an implementation using the juxt/bidi way

Related projects

  • milesian/aop: facility to apply defrecord-wrapper in stuartsierra/component library

License

Copyright © 2014 Juan Antonio Ruz (juxt.pro)

Distributed under the MIT License. This means that pieces of this library may be copied into other libraries if they don't wish to have this as an explicit dependency, as long as it is credited within the code.

Copyright "Hesperidium" image @ clipart

defrecord-wrapper's People

Contributors

tangrammer avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.