Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read from console / standard input #335

Open
tbagrel1 opened this issue Dec 10, 2024 · 1 comment
Open

Read from console / standard input #335

tbagrel1 opened this issue Dec 10, 2024 · 1 comment

Comments

@tbagrel1
Copy link

Hello,
I didn't find a way to read from console (stdin of the current process) using os-lib.
I expected to find such a feature in a lib designed to handle OS interfacing (something like os.read.lines.stream(os.Stdin)).
In the Scala API doc, I only found how to manage standard input of subprocesses, not how to access the standard input of the current process and read from it.
Can you help me? Thanks!

@acloudmovingby
Copy link

acloudmovingby commented Jan 28, 2025

Hi @tbagrel1,

I'm not a maintainer of this library but I stumbled upon your question.

Reading from stdin can be done with just basic Scala, in particular the methods on scala.io.Stdin such as Stdin.readLine().


Now your desire to have a "stream" of input is rather interesting actually. Here are a few options I can think of but I'm not sure any of them are optimal:

  • while loop with mutable var
  • LazyList
  • 3rd party libraries like ZStreams

A while loop (not very "functional programming" but easily understood by most programmers):

var in: String = ""
while ({
	in = StdIn.readLine()
	in != "foo" // terminate loop if user enters "foo"
}) {
	// ...do whatever you want to do with `in`....
}

LazyList (standard Scala's concept of a lazy "stream") has various factory methods in its companion object. This is one of many ways you could skin this cat:

val inputStream: LazyList[String] = LazyList.continually(StdIn.readLine())
inputStream
	.takeWhile(_ != "foo") // end when user enters "foo"
	.map { line =>
		println(s"You entered: $line")
		line
	}
	.toList // You need this! Otherwise the LazyList will never start getting evaluated

I like ZIO ZStreams, but that's somewhat out of the scope of this question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants