Invalid Filename, got xxxxxx but expected xxxxxxxx [duplicate] - clojure

This question already has answers here:
Why does clojure convert dashes in names to underscores in the filesystem?
(2 answers)
Closed 3 years ago.
My ClojureScript app is not compiling. It is throwing the error:
1 | (ns mock-file-system.api-service)
Invalid Filename, got mock_file_system/api-service.cljs but expected mock_file_system/api_service.cljs (or .cljc)
The calling namespace:
(ns mock-file-system.views
(:require
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[mock-file-system.subs :as subs]
[mock-file-system.node :as node]
[mock-file-system.api-service :as api]
))
The required namespace:
(ns mock-file-system.api-service)
Thanks

Looks like you can't use dashes in file names and it converts underscores to dashes in the background.
Fixed by renaming the file with an underscore.

Related

Trying to read data from a text file and populating a list of integers

So, upfront, I'm super new at Clojure so this question may seem basic. I hava a txt file with 1 line that has a set number of intergers separated by a space. I need to read that data and populate a list so I can sort it later. I'm not asking how to do the sort, I need help populating the list with the string from the txt file.
My initial thought is to read the entire line of ints as one string, then split the string with a delimiter, and populate the list with the returned data, but I cant figure out how to do that in clojure. Any guidance is appreciated
Here is one way to do it, using some helper functions. Be sure to also bookmark:
The Clojure CheatSheet
Brave Clojure
Getting Clojure
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require
[schema.core :as s]
[clojure.string :as str]))
(dotest
(let [filename "/tmp/dummy.txt"]
(spit filename "1 2 3 4 5")
(let-spy
[in-str (slurp filename)
nums-str (str/split in-str #"\W+")
nums (mapv #(Integer/parseInt %) nums-str)]
)))
with result:
-------------------------------
Clojure 1.10.0 Java 12
-------------------------------
Testing tst.demo.core
in-str => "1 2 3 4 5"
nums-str => ["1" "2" "3" "4" "5"]
nums => [1 2 3 4 5]

defrecord Class Not Found Exception

I have two files knapsack.clj and core.clj.
There is defrecord Item in knapsack.clj. I want to use it in core.clj but it is giving me error in cider-repl of java.lang.ClassNotFoundException: discrete-optimization.knapsack.Item even though i have require for the knapsack namespace.
Code is here :
;; ---- knapsack.clj ---------
(ns discrete-optimization.knapsack)
;; Item record has weight and value of the Item
(defrecord Item
[weight value])
;; ---- core.clj --------
(ns discrete-optimization.core
(:require [discrete-optimization.knapsack :as KS])
(:import [discrete-optimization.knapsack Item]))
;; doing some knapsack in here.. :)
(and
(= 5 (KS/knapsack-value 5 [(Item. 3 5)]))
(= 5 (KS/knapsack-value 5 [(Item. 3 3) (Item. 2 2)])))
My clojure version is 1.5.1
Solution :
For portable solution :
use ->KS/item when referring to item outside of namespace.
While the answer from xsc is not wrong, my preference is to use the constructor functions that are generated from defrecord and avoiding the Java constructor and Java import -isms. This is likely to be more portable over time/platforms.
;; ---- knapsack.clj ---------
(ns discrete-optimization.knapsack)
;; Item record has weight and value of the Item
(defrecord Item
[weight value])
;; The ->Item constructor is generated automatically
;; ---- core.clj --------
(ns discrete-optimization.core
(:require [discrete-optimization.knapsack :as KS]))
;; doing some knapsack in here.. :)
(and
(= 5 (KS/knapsack-value 5 [(KS/->Item 3 5)]))
(= 5 (KS/knapsack-value 5 [(KS/->Item 3 3) (KS/->Item 2 2)])))
:import references a Java class - and when creating package/class names for those the Clojure compiler converts dashes to underscores. This might thus work:
(:import [discrete_optimization.knapsack Item])

Looking for clojure-csv library example that uses write-csv

I am looking for a clojure-csv library example that uses write-csv. Specifically, how are the arguments formed? I cannot figure out why I am getting the following error below.
Here is my code example with error:
(def x [1 2 3 4])
(write-csv (spit "test.tmp" x) :end-of-line "\n")
ArityException Wrong number of args (3) passed to:
core$write-csv clojure.lang.AFn.throwArity (AFn.java:437)
Thank You.
EDIT Misread your question and didn't realize you were asking about using the library clojure-csv. Going to leave this up in case it helps anyone else using clojure.data.csv.
If you are using leiningen put the following in your project.clj file.
(defproject so "example"
:dependencies [[org.clojure/clojure "1.3.0"]
[org.clojure/data.csv "0.1.2"]])
Example code of creating a function which takes a filename and the data to write to a csv.
(ns so.core
(:require [clojure.data.csv :as csv]
[clojure.java.io :as io]))
(defn csv [filename data]
(with-open [f (io/writer filename)]
(csv/write-csv f data)))
Using csv from the repl.
so.core> (csv "example.csv" [["stack" 1]
["example" 40]])
And here is what example.csv looks like.
$ cat example.csv
stack,1
example,40
Hopefully this helps out.

Calling Function In Separate Clojure Namespace

How do I call a function in one Clojure namespace, bene-csv.core from another namespace, bene-cmp.core? I've tried various flavors of :require and :use with no success.
Here is the function in bene-csv:
(defn ret-csv-data
"Returns a lazy sequence generated by parse-csv.
Uses open-csv-file which will return a nil, if
there is an exception in opening fnam.
parse-csv called on non-nil file, and that
data is returned."
[fnam]
(let [ csv-file (open-csv-file fnam)
csv-data (if-not (nil? csv-file)
(parse-csv csv-file)
nil)]
csv-data))
Here is the header of bene-cmp.core:
(ns bene-cmp.core
.
.
.
(:gen-class)
(:use [clojure.tools.cli])
(:require [clojure.string :as cstr])
(:use bene-csv.core)
(:use clojure-csv.core)
.
.
.
The calling function -- currently a stub -- in (bene-cmp.core)
defn fetch-csv-data
"This function merely loads the two csv file arguments."
[benetrak-csv-file gic-billing-file]
(let [benetrak-csv-data ret-csv-data]))
If I modify the header of bene-cmp.clj
(:require [bene-csv.core :as bcsv])
and change the call to ret-csv-data
(defn fetch-csv-data
"This function merely loads the two csv file arguments."
[benetrak-csv-file gic-billing-file]
(let [benetrak-csv-data bcsv/ret-csv-data]))
I get this error
Caused by: java.lang.RuntimeException: No such var: bcsv/ret-csv-data
So, how do I call fetch-csv-data?
Thank You.
You need to invoke the function, not just reference the var.
If you have this in your ns:
(:require [bene-csv.core :as bcsv])
Then you need to put parentheses around the namespace/alias qualified var to invoke it:
(let [benetrak-csv-data (bcsv/ret-csv-data arg)]
; stuff
)

Why does require in the ns form behave different from the require function

When I require libraries from the ns form I get :
test> (ns test (:require '(clojure.contrib [logging :as log] [sql :as sql]) ))
lib names inside prefix lists must not contain periods
[Thrown class java.lang.Exception]
When I use the require function it works as expected.
test> (require '(clojure.contrib [logging :as log] [sql :as sql]) )
nil
The documentation for ns refers to the documentation of the require function but as they behave differently this is a bit confusing.
The ns form is a macro, and so it doesn't require that you use ' to quote the provided seq.
An example from the Clojure docs:
(ns foo.bar
(:refer-clojure :exclude [ancestors printf])
(:require (clojure.contrib sql sql.tests))
(:use (my.lib this that))
(:import (java.util Date Timer Random)
(java.sql Connection Statement)))