ClojureScript use .requestFullscreen on a video - html5-video

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."]]))

Related

Is there any way to mock a function in clojure?

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.

Spacemacs set tab width

I just migrated from VIM to Spacemacs and would like to change the tab width from default (\t?) to only 2 spaces. I found commands like
(setq-default indent-tabs-mode nil)
and
(setq tab-width 4) ; or any other preferred value
(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)
My problem is that I don't know if they are correct, where in the .spacemacs file I should insert them, and what they even mean.
I found this article:
http://blog.binchen.org/posts/easy-indentation-setup-in-emacs-for-web-development.html
I added this part of the code into my .spacemacs file outside of any function (but before (defun dotspacemacs/user-init () ... )):
(defun my-setup-indent (n)
;; java/c/c++
(setq c-basic-offset n)
;; web development
(setq coffee-tab-width n) ; coffeescript
(setq javascript-indent-level n) ; javascript-mode
(setq js-indent-level n) ; js-mode
(setq js2-basic-offset n) ; js2-mode, in latest js2-mode, it's alias of js-indent-level
(setq web-mode-markup-indent-offset n) ; web-mode, html tag in html file
(setq web-mode-css-indent-offset n) ; web-mode, css in html file
(setq web-mode-code-indent-offset n) ; web-mode, js code in html file
(setq css-indent-offset n) ; css-mode
)
and added the line
(my-setup-indent 2) ; indent 2 spaces width
into the (defun dotspacemacs/user-init () ... ) like this:
(defun dotspacemacs/user-init ()
"Initialization function for user code.
It is called immediately after `dotspacemacs/init', before layer configuration
executes.
This function is mostly useful for variables that need to be set
before packages are loaded. If you are unsure, you should try in setting them in
`dotspacemacs/user-config' first."
(my-setup-indent 2) ; indent 2 spaces width
)
You can also just customize the the standard-indent variable, setting it to 2, by calling the command customize-variable within spacemacs. This will save the customization into your .spacemacs file.
Edit:
to run 'customize-variable' use the hotkey M-x (alt-x on most systems) then type customize-variable in to the prompt.
you can use the search to search for 'standard-indent'

Common Lisp unbound variable / defmacro

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)))

Clojure way of reading large files and transforming data therein

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.

Is clojure's read file structure, i.e. with-open and clojure.java.io/reader, efficient enough for frequent access?

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
))