practicalli / practicalli/clojure

Command line input

Open
#75 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Makefile
Stars
117
Forks
36
PR merge metrics
No merged PRs in 30d

Description

Prompt until a number is entered by the user (repeat until you get the number)

wrap the smallest possible block in the try

(ins)user=> (try (Long/parseLong nil) (catch Exception _))
nil
(ins)user=> (try (Long/parseLong "1") (catch Exception _))
1

More complete solution

(defn get-num []
  (print "Number: ")
  (flush)
  (let [input (read-line)
        num (try 
             (Long/parseLong input)
             (catch Exception _))]
  (if num
    num
    (recur))))

last line should probably be (or num (recur)) but that expands to the same thing anyway

try returns the body of the catch if it is invoked, here the catch implicitly returns nil as there's no body
noisesmith 22 hours ago
you could make it explicit by adding false or nil to the catch
noisesmith 22 hours ago
and yes, clojure treats nil as false in conditionals
Chase 22 hours ago
awesome. thanks for all your help!
Chase 22 hours ago
What exactly does flush do here?
noisesmith 22 hours ago
it means you can get input on the same line as the prompt
noisesmith 22 hours ago
it flushes partial output (newline automatically gets flushed)
Chase 22 hours ago
perfect. That fits the problem description exactly as well. Thank you!
noisesmith 22 hours ago
here's an alternate version (does the same thing, may or may not be clearer)

(defn get-num []
(print "Number: ")
(flush)
(or (try (Long/parseLong (read-line))
(catch Exception _
false))
(recur)))

noisesmith 22 hours ago
also, I've seen (defn safe-long [s] (try (Long/parseLong s) (catch Exception _))) in multiple code bases, sometimes I write it, sometimes someone else does
Chase 22 hours ago
I prefer the first one but both really clear things up for me
Chase 22 hours ago
Awesome. Maybe I should start my own little util file and keep such things in it. (edited)
hindol 22 hours ago
It is also possible to use clojure.edn/read-string and check if the resulting thing is a number?, int? or integer? depending on what you want. That avoids the try/catch as well.
noisesmith 22 hours ago
but it will still throw on eg. ")"
hindol 22 hours ago
Good point.
noisesmith 22 hours ago
I don't like using read-string for user input

lojure 1.10.1
(cmd)user=> (read-string ")")
Execution error at user/eval1 (REPL:1).
Unmatched delimiter: )
(ins)user=> (read-string "#=(java.lang.System/exit 1)")
justin.smith@C02ZW014LVDN ~ %

noisesmith 22 hours ago
that is, #= is read-eval, and it does things you probably don't want
hindol 22 hours ago
I thought edn/read-string did not have the unsafe bits. I may be wrong.
noisesmith 22 hours ago
oh, I missed that you specified clojure.edn

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No file or test is named; start by locating the repository's Clojure CLI or REPL material related to command-line input. Use the issue's get-num examples to identify the relevant entry point, and consider the work complete when input is reprompted until a number is entered.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
cli
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.