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")
Related
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.
how would it be possible to bypass functions that are not existing in DM
such that the main code would still run? Try/catch does not seem to work, e..g
image doSomething(number a,number b)
{
try
{
whateverfunction(a,b)
}
catch
{
continue
}
}
number a,b
doSomething(a,b)
Also conditioning wont work, e.g..
image doSomething(number a,number b)
{
if(doesfunctionexist("whateverfunction"))
{
whateverfunction(a,b)
}
}
number a,b
doSomething(a,b)
thanks in advance!
As "unknown" commands are caught by the script-interpreter, there is no easy way to do this. However, you can construct a workaround by using ExecuteScriptCommand().
There is an example tutorial to be found in this e-book, but in short, you want to do something like the following:
String scriptCallStr = "beep();\n"
scriptCallStr = "MyUnsaveFunctionCall();\n"
number exitVal
Try { exitVal = ExecuteScriptString(scriptCallStr ); }
Catch { exitVal = -1; break; }
if ( -1 == exitVal )
{
OKDialog("Sorry, couldn't do:\n" + scriptCallStr )
}
else
{
OKDialog( "All worked. Exit value: " + exitVal )
}
This works nicely and easy for simple commands and if your task is only to "verify" that a script could run.
It becomes clumsy, when you need to pass around parameters. But even then there are ways to do so. (The 'outer' script could create an object and pass the object-ID per string. Similarly, the 'inner' script can do the same and return the script-object ID as exit-value.)
Note: You can of course also put doesfunctionexist inside the test-script, if you do only want to have a "safe test", but don't actually want to execute the command.
Depending on what you need there might also be another workaround solution: Wrapper-functions in a library. This can be useful if you want to run the same script on different PCs with some of which having the functionality - most likely some microscope - while others don't.
You can make your main-script use wrapper methods and then you install different versions of the wrapper method script scripts as libraries.
void My_SpecialFunction( )
{
SpecialFunction() // use this line on PCs which have the SpecialFunction()
DoNothing() // use alternative line on PCs which don't have the SpecialFunction()
}
My_SpecialFunction( )
I have used this in the past where the same functionality (-stage movement-) required different commands on different machines.
Just a quick question. I was just wandering whether or not, I still have to "return;" even in a void function?
At the moment, even in methods which are not returning a variable/etc... I still have "return" at the end of the method.
So do I still need this? Because I swear without it, it does NOT return to where it was called from.
EG:
-(void)viewDidLoad {
[super viewDidLoad];
// Run other setup code....
// Run method 1.
[self method_01];
// Run next bit of code....
}
-(void)method_01 {
// Run code....
return;
}
Do I still have to do it like the above example?
Thanks for your time, Dan.
If the return is at the end of the method, it doesn't make any difference.
-(void) doSomethingWithX:(int) X
{
..........................
........some Code.........
..........................
return ;
}
The control would reach the caller one the method execution completes. Marking a return does the same.
However in a condition like below,
-(void) doSomethingWithX:(int) X
{
if(X>10)
{
return;
}
..........................
........some Code.........
..........................
}
The some code will not be executed if your X value is greater than 10. So, by default control return to the caller at the end of method. Use return if you want to force a return to caller in between the method execution.
You do not. The method will return to its previous point of execution once it reaches the end of the current scope.
You do not need to call return in methods that are defined with void and thus do not return a value.
There are times when you would want to call return in such methods, such as if you want to exit out of the method without executing the remaining code, if a particular condition is met:
if (iHaveDeterminedIAmFinished) {
return;
}
... // code that would otherwise execute.
Other than this, it would be bad practice to routinely include return at the end of every method. Every Objective-C method returns without exception, if it reaches the end of the method without a previous return. Therefore, this practice would not be more clear to a reader who has any familiarity with Objective-C. Indeed, it would likely confuse other developers reading your code who would be left wondering what the intention was. It would be likely to appear like something had been omitted from the end of the method, since there would be no reason for including this return otherwise. In short, I suggest it would be bad practice to include unnecessary return calls at the end of methods.
Because I swear without it, it does NOT return to where it was called from.
Something else is going on here. You may well need to figure out what it is, but it is not correct that the absence of return calls would prevent a return to the point of execution. Either it is returning, and you're not realising it for some reason, or something else is happening in your code.
You can do it either way. It should return automatically without an explicit return.
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
}
}
i am processing a ragged semicolon delimited file using script component as transformation.
The component is able to process the data and load to oledb destination. But when error is found it should stop processing further. As i am using try catch block the component doesn't fail and continue to process till the end.
Is there any way i could stop the processing further without failing the component/package?
Let me know if any other information/details required?
sample code:
str.split(";");
if(column[0] == "H")
{
col1=Column[3];
}
if(column[0] != "T")
{
try
{
Row.col1=Column[0];
Row.col2=Column[1];
.....
}
catch
{
update the variable to check if we have error in file.
}
}
Thank you for your time.
The general idea will be that you want to use try/catch blocks to ensure the data processing itself doesn't abort. Once you know your script isn't reporting a failure back to the engine, it's a simple process to not call the AddRow()
Pseudocode
foreach(line in fileReader)
{
try
{
// perform dangerous operations here
// Only add row if you have been able to parse current line
Output0Buffer.AddRow();
Output0Buffer.Col1 = parsedContent;
}
catch
{
// Signal that we should break out of the loop
// do not propagate the error
// You might want to do something though so you know you
// have an incomplete load
break;
}
}
If you are looking to just skip the current bad line, you can substitute continue for the break above.
C# loop - break vs. continue
I didn't get any help from anywhere, But as a work around i have placed a return statement in the code. It checks the error variable if it's true then i will return without processing further. But the thing still is it processes the whole file :(. But it works!!!