Giter Site home page Giter Site logo

slamhound's Introduction

Slamhound

They sent a slamhound on Turner's trail in New Delhi, slotted it
to his pheromones and the color of his hair. It caught up with him
on a street called Chandni Chauk and came scrambling for his
rented BMW through a forest of bare brown legs and pedicab
tires. Its core was a kilogram of recrystallized hexogene and
flaked TNT. He didn't see it coming. The last he saw of India was
the pink stucco facade of a place called the Khush-Oil Hotel.

Because he had a good agent, he had a good contract. Because he
had a good contract, he was in Singapore an hour after the
explosion. Most of him, anyway. The Dutch surgeon liked to joke
about that, how an unspecified percentage of Turner hadn't made it
out of Palam International on that first flight and had to spend
the night there in a shed, in a support vat.

It took the Dutchman and his team three months to put Turner
together again. They cloned a square meter of skin for him, grew
it on slabs of collagen and shark-cartilage polysaccharides. They
bought eyes and genitals on the open market. The eyes were green.

-- Count Zero, page 1. By William Gibson

Slamhound rips your ns form apart and reconstructs it. No Dutch surgeon required.

Add [slamhound "1.5.0"] to the :dependencies of your :user profile.

Screencast

http://vimeo.com/user133347/slamhound-screencast

Leiningen Usage

Make an alias for run -m slam.hound in your :user profile:

  :aliases {"slamhound" ["run" "-m" "slam.hound"]}

Take a namespace with a sparse ns form that won't compile:

$ cat src/my/namespace.clj # before: ns form is missing clauses

(ns my.namespace
  "I have a docstring.")

(defn -main [& args]
  (pprint args)
  (io/copy (ByteArrayInputStream. (.getBytes "hello"))
           (first args)))

Then run slamhound on it:

$ lein slamhound src/my/namespace.clj # [... thinking ...]

$ cat src/my/namespace.clj  # after: spits out new ns form
(ns my.namespace
  "I have a doc string."
  (:require [clojure.java.io :as io]
            [clojure.pprint :refer [pprint]])
  (:import (java.io ByteArrayInputStream)))

Like magic.

Running on a directory will perform the same operation on every .clj file inside.

Repl Usage

You can reconstruct namespaces from a repl to avoid the slow startup time:

user=> (require '[slam.hound :refer [reconstruct]])
nil
user=> (println (reconstruct "src/my/namespace.clj"))
(ns my.namespace
  "I have a doc string."
  (:require [clojure.java.io :as io]
            [clojure.pprint :refer [pprint]])
  (:import (java.io ByteArrayInputStream)))

Or to reconstruct files in place:

user=> (slam.hound/-main "src/my/namespace.clj")
nil
;; Reload the file in your editor to pick up changes

Emacs Usage

The included slamhound.el allows for convenient access within nREPL or SLIME sessions via M-x slamhound. Install manually or via Marmalade.

Vim Usage

Install vim-slamhound for use of the :Slamhound command within Clojure buffers.

Shortcomings

Slamhound will only find references to vars in a namespace that are consumed within the namespace itself. For example, if you have a macro that refers to a var inside syntax-quote (backtick), but the macro is only called from other namespaces, then Slamhound won't detect the reference and will instead report the failure in the namespace in which the macro is called.

You can work around this problem by attaching dummy metadata to the defmacro form to prevent it from compiling without the necessary vars being present:

(defmacro ^{:requires [a/b c/d]} let-qp [q p & body]
  `(let [~'q a/b
         ~'p c/d]
     ~@body))

Slamhound will also not find references to fully-qualified vars or vars resolved at runtime since it relies on detecting compilation failures to determine when it's done.

Slamhound aggressively loads all namespaces on the classpath on first invocation. This is computationally expensive, so first use may be slow, though subsequent calls should be relatively quick.

This also taxes the class loading system, so there is a possibility that the JVM may run out of PermGen space in large projects. If this happens, try running your JVM with the following options:

-Xmx5g -XX:+CMSClassUnloadingEnabled -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=128M

Leiningen 1.x

The lein-slamhound plugin is deprecated, and the :aliases approach above is recommended for users of Leiningen 2. However, if you are still using Leiningen 1.x you can use the run task:

$ lein run -m slam.hound src/foo

Since Leiningen 1.x doesn't support partially-applied aliases, you would have to make a shell alias if you don't want to type the full invocation out every time.

License

Copyright © 2011-2012 Phil Hagelberg and contributors

Distributed under the Eclipse Public License, the same as Clojure.

slamhound's People

Contributors

technomancy avatar guns avatar alexbaranosky avatar jsnikeris avatar radicalzephyr avatar tomfaulhaber avatar amalloy avatar puercopop avatar joegallo avatar

Watchers

 avatar James Cloos avatar  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.