Is there any way to mock a function in clojure. For example I have this function: (defn a [x] (utils/count x)) I need to write a test, but I do not know how to mock the utils/count (for example). what if I have several functions inside the same function and I need to test it? (defn a [x] (utils/count x) (utils/count2 x) (test/other x))
You can use with-redefs e.g.
(deftest t
(with-redefs [utils/count (fn [x] 2)
utils/count2 (fn [x] 3)
test/other (fn [x y] :result)]
(let [result (a 2)])))
See also https://ask.clojure.org/index.php/9077/how-do-you-mock-in-clojure which suggests organizing your code so you don't need mocks, where possible.
Related
How can I .requestFullscreen (or .-volume) on a video from another element ?
I've tried using this-as macro and getElementByID but my editor and Figwheel are unhappy when I try to make this function call.
Here is one way to do it:
(defn foo []
(let [v (atom nil)]
[:div
[:button
{:on-click
(fn [e]
(when #v
(cond
(.-requestFullscreen #v) (.requestFullscreen #v)
(.-mozRequestFullScreen #v) (.mozRequestFullScreen #v)
(.-webkitRequestFullScreen #v) (.webkitRequestFullscreen #v)
:else nil)))}
"Fullscreen"]
[:video
{:ref
(fn [elem]
(when elem
(reset! v elem)))
:src "https://archive.org/download/WebmVp8Vorbis/webmvp8.webm"}
"Sorry, your browser doesn't support embedded videos."]]))
I need to make the function defmacro for my meta-circular interpreter that can read this syntax:
pseudoscheme> (defmacro (minus x y) (list ‘- y x))
MINUS
pseudoscheme> (expand-macro '(minus 3 2))
(- 3 2)
When I use this:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
(progn
`(setf (macro-function ',name)
(lambda (,form ,env))
(destructuring-bind ,args (rest, form) ,#body))
name
)
)
)
and then:
(my-defmacro (min a b)(list '- a b))
I get this error:
Error: The variable MIN is unbound.
I can't understand why.
-----EDITED-----
If I use this:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env))
(destructuring-bind ,args (rest, form) ,#body))
',name)
)
)
and then:
(my-defmacro (min a b)(list '- a b))
I get this error:
Error: Odd number of args to SETF: ((MACRO-FUNCTION (QUOTE PLUS)) (LAMBDA (#:G786 #:G787)) (DESTRUCTURING-BIND (A B) (REST #:G786) (LIST # A B)))
Your my-defmacro works for you host CL system, but I get the feeling you want macro capabilities in your interpreter and this won't do it. (except if ythe interpreter environment is the global host implementations environment, but that would make a lot of challenges)
I don't know how you do compound procedures in your evaluator but when my evaluator gets a (lambda (x) (+ x x)) it is turned into (compound-procedure <env> (x) (+ x x)). My macros turn into almost the same except the first element is compound-syntax.
Every evaluated operator has a tag which tells it what it is (one of primitive-syntax, primitive-procedure, compound-syntax, compound-procedure) and I only need a general way of dealing with those 4.
The real difference between a compound procedure and compound syntax is that the arguments gets evaluated for a procedure and in a compound syntax the result gets evaluated.
So. Have you implemented so that ((lambda (x) (+ x x)) 5) works? Well, then you'll almost implemented macros as well. This is of course not true for a compiler, since this approach would expand the code every time it's run instead of expanding once when the closure gets created. (Optimizations is no way to go on the first version anyway)
For your 'edited code' you have a misplaced paren:
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env)) ;; <== HERE
(destructuring-bind ,args (rest, form) ,#body))
',name)
)
)
which leads to setf having three subforms. Rewrite it like this (while using standard Lisp formatting):
(defmacro my-defmacro ((name &rest args) &body body)
(let ((form (gensym))
(env (gensym)))
`(progn (setf (macro-function ',name)
(lambda (,form ,env)
(destructuring-bind ,args (rest, form)
,#body)))
',name)))
I am processing a Subrip subtitles file which is quite large and need to process it one subtitle at a time. In Java, to extract the subtitles from file, I would write a method with following signature:
Iterator<Subtitle> fromSubrip(final Iterator<String> lines);
The use of Iterator gives me two benefits:
The file is never in the memory in its entirety, nor is any of its transformed stage.
An abstraction wherein I can loop over a collection of Subtitle objects without the memory overhead.
Since iterators are by nature imperative and mutable, they're probably not idiomatic in Clojure. So what is the Clojure way to deal with this sort of situation?
As Vladimir said, you need to handle the laziness and file closing correctly. Here's how I did it, as shown in "Read a very large text file into a list in clojure":
(defn lazy-file-lines
"open a (probably large) file and make it a available as a lazy seq of lines"
[filename]
(letfn [(helper [rdr]
(lazy-seq
(if-let [line (.readLine rdr)]
(cons line (helper rdr))
(do (.close rdr) nil))))]
(helper (clojure.java.io/reader filename))))
read all files from a directory, a lazy way.
using go black and channel.
code:
(ns user
(:require [clojure.core.async :as async :refer :all
:exclude [map into reduce merge partition partition-by take]]))
(defn read-dir [dir]
(let [directory (clojure.java.io/file dir)
files (filter #(.isFile %) (file-seq directory))
ch (chan)]
(go
(doseq [file files]
(with-open [rdr (clojure.java.io/reader file)]
(doseq [line (line-seq rdr)]
(>! ch line))))
(close! ch))
ch))
invoke:
(def aa "D:\\Users\\input")
(let [ch (read-dir aa)]
(loop []
(when-let [line (<!! ch )]
(println line)
(recur))))
================
reify the Iterable interace, can be used in java.
MyFiles.clj:
(ns user
(:gen-class :methods [#^{:static true} [readDir [String] Iterable]])
(:require [clojure.core.async :as async :refer :all
:exclude [map into reduce merge partition partition-by take]]))
(defn -readDir [dir]
(def i nil)
(let [ch (read-dir dir)
it (reify java.util.Iterator
(hasNext [this] (alter-var-root #'i (fn [_] (<!! ch))) (not (nil? i)))
(next [this] i))
itab (reify Iterable
(iterator [this] it))]
itab))
java code:
for (Object line : MyFiles.readDir("/dir")) {
println(line)
}
You can use lazy sequences for this, for example, line-seq.
You must be careful, however, that the sequence returned by line-seq (and other functions which return lazy sequences based on some external resource) never would leak out of e.g. with-open scope because after the source is closed, further reading from lazy sequence will cause exceptions.
Suppose I write a function to parse data from a txt file with with-open and clojure.java.io/reader, and then I wrote another function to call the reader function multiple of times in order to process data, e.g.
(defn grabDataFromFile [file patternString]
(let [data (atom [])]
(with-open [rdr (clojure.java.io/reader file)]
(doseq [line (line-seq rdr)]
(if (re-matches (re-pattern patternString) line) (swap! data conj line))))
#data))
(defn myCalculation [file ]
(let [data1 (grabDataFromFile file "pattern1")
data2 (grabDataFromFile file "pattern2")
data3 (grabDataFromFile file "pattern3")]
;calculations or processes of data1, data2, data3....))
My question is, inside this myCalculation function, is the underlying code smart enough to open the file just once with clojure reader, and get all data needed in one shot? Or does it open and close the file as many times as number of calls for function grabDataFromFile ? ( In this example, 3)
A follow up question would be, what can I do to speed up if the reader is not smart enough, and if I have to intentionally separate "parser" code with "processing" code?
grabDataFromFile will open and close reader (on exit) every time it is called. The underlying code cannot be that smart such that a function can detect the context of its caller without some explicitly provided information.
Make grabDataFromFile to accept another function which is your parser logic that operates on each line (or it could be any function that you want to perform on each line)
(defn grabDataFromFile [file patternString process-fn]
(with-open [rdr (clojure.java.io/reader file)]
(doseq [line (line-seq rdr)]
(process-fn line))))
(defn myCalculation [file]
(let [patterns [["pattern1" (atom [])]
["pattern2" (atom [])]
["pattern3" (atom [])]]
pattern-fns (map (fn [[p data]]
(fn [line]
(if (re-matches (re-pattern p) line)
(swap! data conj line)))) patterns)
pattern-fn (apply juxt pattern-fns)]
(grabDataFromFile file pattern-fn)
;perform calc on patterns atoms
))
I think I read somewhere that you could bind multiple definitions to a single name in scheme. I know I might be using the terminology incorrectly. By this I mean it is possible to do the following (which would be really handy to defining an operator)?
I believe I read something like this (I know this is not real syntax)
(let ()
define operator "+"
define operator "-"
define operator "*"
define operator "/"))
I want to test another variable against every operator.
I'm not really sure what you're asking. Do you want a single procedure that can handle different types of arguments?
(define (super-add arg1 arg2)
(cond ((and (string? arg1) (string? arg2))
(string-append arg1 arg2))
((and (number? arg1) (number? arg2))
(+ arg1 arg2))
(else
(error "UNKNOWN TYPE -- SUPER-ADD"))))
(super-add "a" "b") => "ab"
(super-add 2 2) => 4
Are you interested in message passing?
(define (math-ops msg) ;<---- returns a procedure depending on the msg
(cond ((eq? msg 'add) +)
((eq? msg 'sub) -)
((eq? msg 'div) /)
((eq? msg 'multi) *)
(else
(error "UNKNOWN MSG -- math-ops"))))
((math-ops 'add) 2 2) => 4
((math-ops 'sub) 2 2) => 0
Also the proper syntax for a let binding:
(let (([symbol] [value])
([symbol] [value]))
([body]))
(let ((a 2)
(b (* 3 3)))
(+ a b))
=> 11
It will be very hard to help more than this without you clarifying what it is you are trying to do.
EDIT: After your comment, I have a little bit better of an idea for what you're looking for. There is not way to bind multiple values to the same name in the way that you mean. You are looking for a predicate that will tell you whether the thing you are looking at is one of your operators. From your comment it looked like you will be taking in a string, so that's what this is based on:
(define (operator? x)
(or (string=? "+" x) (string=? "-" x) (string=? "*" x) (string=? "/" x)))
If you are taking in a single string then you will need to split it into smaller parts. Racket has a built in procedure regexp-split that will do this for you.
(define str-lst (regexp-split #rx" +" [input str]))
You may be referring to the values construct, which "delivers arguments to a continuation". It can be used to return multiple values from a function. For example,
(define (addsub x y)
(values (+ x y) (- x y)))
(call-with-values
(lambda () (addsub 33 12))
(lambda (sum difference)
(display "33 + 12 = ") (display sum) (newline)
(display "33 - 12 = ") (display difference) (newline)))