How do I exit a Rust program early from outside the main function? - system

I am in the process of writing a bash clone in Rust. I need to have my program exit when the user types exit. In previous iterations of my program, before I added more complicated features, I used return to get out of the loop that was prompting the user for input. This logic is now in a function, because of the way I am implementing built in shell functions, so when I return it just jumps out of the function back into the control loop, instead of short-circuiting the control loop and ending the program.
I realize that I could probably return a boolean when the user types exit and exit the loop, but I would like to at least know if Rust has a way to terminate programs early, similar to Java's System.exit(), as this is useful for certain types of programs.

Rust 1.0 stable
std::process::exit() does exactly that - it terminates the program with the specified exit code:
use std::process;
fn main() {
for i in 0..10 {
if i == 5 {
process::exit(1);
}
println!("{}", i);
}
}
This function causes the program to terminate immediately, without unwinding and running destructors, so it should be used sparingly.
Alternative (not recommended) solution
You can use C API directly. Add libc = "0.2" to Cargo.toml, and:
fn main() {
for i in 0..10 {
if i == 5 {
unsafe { libc::exit(1); }
}
println!("{}", i);
}
}
Calling C functions cannot be verified by the Rust compiler, so this requires the unsafe block. Resources used by the program will not be freed properly. This may cause problems such as hanging sockets.
As far as I understand, the proper way to exit from the program is to terminate all threads somehow, then the process will exit automatically.

panic!("Oh no something bad has happened!")
Example:
if a * g < 0f32 { panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); }
In older documentation, you will see this as fail!("Oh no something bad here has happened.")
For some reason, this macro was changed from fail to panic. Panic is the way to fail, if you must.
[edit] I am sorry. It looks like you should be testing input for the string "exit," which would depend on how you are taking input (by line or by args). Then you can have the program break out of the loop on the condition that the exit is detected.
Example:
loop {
if exit_found { break }
else {
// your thing, which also looks for exit_found
}
}

Related

Using require() later in code and should one handle any exceptions thrown thereby

I have a kotlin class with a method
loadElements(e: Iterable<Int>) {
}
This then constructs a new copy of that Iterable as an ArrayList<Int> within the object.
It is a requirement that all the elements in that ArrayList<Int> be non-negative. It is considered a breach of contract by the caller if that is not met. I've been led to believe that "breach of contract" is something to be tested by require(), whereas check() is for testing logic internal to that method. Is this correct ?
All the examples I have seen, have the require() as the very first lines of code within the method. Is it, however, acceptable to run require() in a loop, like this ?
public fun loadElements(e: Iterable<Int>) {
elementArray.clear()
e.forEach {
require(it>=0)
elementArray.add(it)
moduleCount += it
}
if (elementCount %2 == 1)
elementArray.add(0)
check(elementCount %2 == 0)
computeInternalSizes()
}
Thing is, this means that part of the object's internals may already be set-up by the time the require() breach is detected: i.e., moduleCount will be wrong and computeInternalSizes() will never get called.
Now, of course I could just use a separate pass, with the first one checking for the require() condition, and then doing all the real work thereafter. This would mean that if the input came in as a Sequence<Int>, it would be forced to be terminal and multi-iterable.
If the require() throws, I would like to assume that the program cannot continue because a design error has occurred somewhere. However, if someone traps the resultant exception, and continues, I will end-up with an incoherent object state.
What is best practice for handling conditions where incoming parameter breaches won't be noticed until some significant unrewindable work has been done ?
I tried using a separate pass for checking for non-negativity. This worked perfectly well but, given that it could be coming from a Sequence or similar, I don't want to have to build the whole sequence, and then traverse that sequence again.
I tried using check(). This works, but it just shows up as an inconsistency in object state, rather than flagging up the incoming parameter validation, which is making a breach of contract look like an internal design fault, and just delaying the inevitable.
I've tried putting try/catch/finally all over the place, but this is an excessive amount of code for such a simple thing.
I'm not even sure if a program should attempt recovery if a require() fails.
In general you avoid situations like this, by reducing the scope of mutability in your code.
The difference between require and check is mostly a convention. They throw different Exceptions, namely IllegalArgumentException and IllegalStateException respectively. As the type of the Exceptions suggest, former is suited for validating the (user) input to a method whereas the latter is designed to check intermediate states during the runtime.
Exceptions in Kotlin should be handled as such, being an Exception that should not occur regularly. See also the Kotlin documentation why there are no checked exceptions in Kotlin.
You did not write the name of your surrounding Kotlin class, thus I'll call it Foo for the time being.
Rather than providing a function on Foo, that mutates the internal state of Foo, you could create new instances of Foo based on the Iterable<Int> / Sequence<Int>. This way, you only ever have an Foo object when its in a valid state.
private class Foo(source: Iterable<Int>) {
private val elementArray = ArrayList<Int>()
private val moduleCount: Int
init {
var internalCount = 0
for (count in source) {
require(count > 0)
elementArray.add(count)
internalCount += count
}
moduleCount = internalCount
if (elementArray.size % 2 == 1) {
elementArray.add(0)
}
check(elementArray.size % 2 == 0)
// ...
}
}
Alternatively, if you want / need to keep the interface as described in your question but also avoid the invalid state, you could make use of an intermediate copy.
As you're copying the incoming Iterable<Int> / Sequence<Int> into an ArrayList<Int> I assume you're not working with very large collections.
private class Foo(source: Iterable<Int>) {
private val elementArray = ArrayList<Int>()
private var moduleCount = 0
public fun loadElements(source: Iterable<Int>) {
val internalCopy = ArrayList<Int>()
for (count in source) {
require(count >= 0)
internalCopy.add(count)
}
elementArray.clear()
for (count in internalCopy) {
elementArray.add(count)
moduleCount += count
}
if (elementArray.size % 2 == 1) {
elementArray.add(0)
}
check(elementArray.size % 2 == 0)
// ...
}
}

To nest conditionals inside your Main, or to not nest conditionals

Issue
Attempting to identify which is the best practice for executing sequential methods. Either, nesting conditionals one after another, or nesting conditionals one inside another, within a main function. In addition, if you could supply "why" one method would be better than the other besides what's most acceptable, I'd sincerely appreciate it. Here are my examples:
Nesting one after another
int main()
{
// conditional 1
if (!method_one())
{
... do something
}
else
{
... prompt error for method 1!
}
// conditional 2
if (!method_two())
{
... do something
}
else
{
... prompt error for method 2!
}
// conditional 3
if (!method_three())
{
... do something
}
else
{
... prompt error for method 3!
}
return 0;
}
Nesting one inside another
int main()
{
// conditional 1
if (!method_one())
{
if (!method_two())
{
if (!method_three())
{
... next steps in sequence
}
else
{
... prompt error for method 3!
}
... prompt error for method 2!
}
... prompt error for method 1!
}
return 0;
}
Observations
I've seen both used, however, not sure which is better practice and/or more commonly acceptable.
The two options aren't actually entirely logically identical - in the "Nesting one after another", for example, method_two() will run even if method_one() fails; if method_two() has any side effects this may be undesirable. Furthermore, if both method_one() and method_two() are destined to fail, "Nesting one after another" will print two error prompts, whereas 'Nesting one inside another" will only error prompt on method_one().
You could close the difference by appending a goto End at the end of each else in "Nesting one after another", so it skips over the remaining checks, but the use of goto would probably get you slapped. Alternatively, you could return at the end of each else, perhaps with an error code, and let whoever is calling your main function deal with understanding what went wrong.
With that in mind, "Nesting one after another" is probably easier to read and understand, since there's less indentation/the code is kept flat, and what happens on failure is immediately next to the check. (That 2nd point can be addressed by reordering the error prompt for method_one() to before the check for method_two() for "Nesting one inside another")

is whenever signal() in react block order dependent?

I have a small program which runs until a SIGINT is received or two lines (press enter twice) from stdin are received. The react block logic is:
react {
whenever signal(SIGINT) {
say "Got signal";
exit;
}
whenever $*IN.lines.Supply {
say "Got line";
exit if $++ == 1 ;
}
}
Program will exit on two entered lines as expected.
However CTRL-C will not do anything, unless it is followed by a line (enter).
If I switch the order of the whenever blocks, the program is interrupted by a SIGINT but doesn't execute the signal whenever block
react {
whenever $*IN.lines.Supply {
say "Got line";
exit if $++ == 1 ;
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
Is there some other setup required before using the signal sub? Is the order of whenever blocks important in a react block?
Update
So it seems the lines() call is blocking the react block from executing (thanks #HÃ¥kon). I kind of get it.
When comparing to a similar code structure for reading a socket I'm confused though. The presence of data (or lack of) has no effect on the signal handler executing and it can read lines just fine in this example:
my $listener=IO::Socket::Async.listen("0.0.0.0",4432);
react {
whenever $listener {
whenever $_.Supply.lines() {
say "Got line";
}
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
#testing with:
# curl http://localhost:4432
Why does this behave so different to my original code?
The order doesn't matter provided the data sources really behave in an asynchronous manner, which unfortunately is not the case here. The Supply coercer on a Seq does not introduce any concurrency, and does immediately try to produce a value to emit on the Supply, which in turn blocks on reading from $*IN. Thus, the second subscription doesn't have chance to be set up; the same underlying issue causes the other problems observed.
The solution is to force the reading to happen "elsewhere". We can do that with Supply.from-list(...), plus telling it we really do want to use the current scheduler rather than its default CurrentThreadScheduler. Thus, this behaves as wanted:
react {
whenever Supply.from-list($*IN.lines, scheduler => $*SCHEDULER) {
say "Got line";
exit if $++ == 1 ;
}
whenever signal(SIGINT) {
say "Got signal";
exit;
}
}
It's likely this area will be revised somewhat in future Perl 6 versions. The current behavior was well-intended; the design principle was to avoid implicit introduction of concurrency, following the general principle that supplies are a tool for managing concurrency that inherently exists, rather than for introducing it. However, in reality, the lack of concurrency here has probably tripped up more folks than it has helped. (Further, we may look into offering real non-blocking file I/O, rather than building it from sync file I/O + threads.)
Here is a variant that runs the signal handler (based on this answer), but unfortunately autoflushing of $*IN seems to be turned off:
my $lines = supply {
whenever start $*IN.lines.Supply {
whenever .lines { .emit }
}
}.Channel;
react {
whenever signal(SIGINT) {
say "Got signal";
exit;
}
whenever $lines {
say "Got line: '{$_}'";
exit if $++ == 1;
}
}
Now you have to press CTRL-D to print the lines, and then it print all lines entered as a concatenated string and after that $*IN is closed.. How can I turn on autoflushing for $*IN in this case?

Kotlin use block function is not called on File.printWriter()

I'm new to Kotlin and I'm trying to do a simple task - create and write to a file. For some reason, using use() with a block function on printWriter() doesn't actually write.
File("test2.txt").printWriter().use { out ->
{
println("hmmm")
out.println("what's up")
log.info { "finished writing" }
}
}
In fact, the block function doesn't seem to be called at all - both "hmmm" and "finished writing" never show up, although the file itself is created (but is totally empty).
The much simpler writeText() works just fine - the file is created and the given text is written to the file.
File("test3.txt").writeText("testing")
What am I doing wrong in my use() version?
Edit: it seems to be a syntax issue with my block function. Looks like I have an extra pair of brackets? Would love a brief explanation as to why it makes it not work.
Edit 2: I think I understand now. The way I wrote it, I was essentially returning the block function itself rather than running through it.
So the problem was that the way I was writing the block function caused it to just return the inner block function, and not actually call it.
Here are two ways that work:
File("test2.txt").printWriter().use {
println("hmmm")
it.println("what's up")
log.info { "finished writing!" }
}
File("test2.txt").printWriter().use(fun(out) {
println("hmmm")
out.println("what's up")
log.info { "finished writing!" }
})
Although, for my purposes writeText() actually works just fine and is much shorter haha.

Whats the best way to write an iterator supporting multiple logic branches?

In Rust I've started writing iterators, converting them from code which took a callback function.
I ran into the problem where the code that used a callback in multiple branches of the function didn't convert so cleanly into a Rust iterator.
To give some pseudo-code.
// function using callbacks where the caller can exit at any time,
// can be used in a similar way to an iterator.
fn do_stuff(args, callback_fn(cb_args)) {
// define a, b, c... args
if callback_fn(a, b, 0) == false { return; }
for i in 0..n {
if callback_fn(c, d, i) == false { return; }
}
if callback_fn(e, f, -1) == false { return; }
}
Converting this to an iterator was rather awkward since I needed to store some state representing each branch.
impl Iterator for MyStruct {
fn next(&mut self) -> Option<MyResult> {
let out = match (self.state) {
0 => {
self.state += 1;
Some(MyResult(self.a, self.b, 0))
},
1 => {
self.i += 1;
if self.i == self.n {
self.state += 1;
}
Some(MyResult(self.c, self.d, self.i - 1))
},
2 => {
self.state += 1;
Some(MyResult(self.e, self.f, -1))
},
_ => {
None
},
}
return out;
}
// --- snip
With the example above, this is arguably acceptable, (if a little awkward). Consider cases with multiple for loops, variable scopes, where its much harder to track state.
While I didn't try these, I imagine there are some ways to achieve this which in most cases are less-then-ideal workarounds:
Using the callback version, building a vector, then iterating over it... (works but defeats the purpose of using an iterator, no way to early exit and avoid creating the entire data set for eg).
Writing an iterator which communicates with a thread that uses similar logic to the callback version.(while possible, the overhead of creating OS threads makes it a poor choice in many cases).
Besides the workarounds above:
Are there ways to write iterators like the example given, with less convoluted logic?Ideally more like the example that uses callbacks.
Otherwise are there other ways to handle this?
Or is this simply not supported in Rust?
Note, the same logic applies coming from Python generators (using yield instead of a callback, using callbacks as an example here since they're ubiquitous with first class functions).
Languages like C# and Python provide a way to generate iterators from methods written using a special yield keyword. As of Rust 1.11, there is no such feature in the language. However, such a feature is planned (see RFC) (indeed, yield is a reserved keyword!) and would likely work as in C# (i.e. the compiler would generate a struct with the necessary state and implementation for Iterator).
In the meantime, you could try Stateful, a project that attempts to provide this feature. (This blog post explains how Stateful works, and the challenges involved.)