I'm pretty much new to Objective C but I've had some experience in Visual Basic. What's the equivalent of the Exit Sub statement to stop executing code if conditions aren't met? I'm talking along the lines of
If Some.Condition.Is.Not.Met Then
Exit Sub //Please don't execute any more code in this method
Is this the correct way to make it work?
-(BOOL)methodThatQuitsOut {
[SomeCode GoesHere];
Other.code = Goes.here;
if (condition != present) {
return NO;
}
Does this code continue to run?;
}
returning from a function does just that; it returns, and control is passed back to the call-e. So no, the code below the return will not execute.
I would note that this would have taken about 30 seconds to test yourself.
Related
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")
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 implementing similar type of thing- I have some message box in the else part of the code below..what I get on debugging is that - I have same message box again and again and it doesn't end (which makes my program crash and I need to restart my laptop)..Is there any solution for it? I am using MFC application and creating a button on window explorer's preview pane. Every thing is fine but this is the problem that once if I enter in the loop below I am not able to come out (I mean there is some thing in DispatchMessage or TranslateMessage which calls this function again and again)..I couldn't find whats that ??
the code is as follow-
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
//Onee message box here
}
}
finally i found that when i return true; in this loop the control will come out of the loop(but its not in good approach) but this getmessage was not useful for me infact when i reomved it my program was working fine. In its presence it was having infinite loop.
Because i created the dialog using CreateDialogParam() and then DialogProc is called through this CreateDialogParam() and then i used WM_Commnands to handle the message received according to the application and i feel no use of this getmessage (please point anyone if i am wrong)
I just asked a question that helps about using generics (or polymorphism) to avoid duplication of code. I am really trying to follow the DRY principle.
So I just ran into the following code...
Sub OutputDataToExcel()
OutputLine("Output DataBlocks", 1)
OutputDataBlocks()
OutputLine("")
OutputLine("Output Numbered Inventory", 1)
OutputNumberedInventory()
OutputLine("")
OutputLine("Output Item Summaries", 1)
OutputItemSummaries()
OutputLine("")
End Sub
Should I rewrite this code to be as follows using the Action delegate...
Sub OutputDataToExcel()
OutputData("Output DataBlocks", New Action(AddressOf OutputDataBlocks))
OutputData("Output Numbered Inventory", New Action(AddressOf OutputNumberedInventory))
OutputData("Output Item Summaries", New Action(AddressOf OutputItemSummaries))
End Sub
Sub OutputData(ByVal outputDescription As String, ByVal outputType As Action)
OutputLine(outputDescription, 1)
outputType()
OutputLine("")
End Sub
I realize this question is subjective. I am just wondering about how religiously you follow DRY. Would you do this?
Seth
I've seen this called the "Hole in the middle" pattern. The "Real World Functional Programming" book mentions it. Here's a link.
http://enfranchisedmind.com/blog/posts/the-hole-in-the-middle-pattern/
See, there’s a pattern I’ve gotten
used to in Ocaml- and I’d even used it
in Perl, which I think of as the “hole
in the middle” pattern. The basic idea
is that you have two pieces of code
that are almost exactly identical,
except for that little middle part
there. The idea is that you factor out
the common code into a single
function, which takes a function
pointer as an argument. The middle
part in the shared code is replaced by
a call to the function pointer, and
the two places which are being
combined simply call the combined
function with a pointer to a function
that contains the unique part.
I wouldn't say I use it all the time, but I have used Action delegate to avoid code duplication. One scenario where I have used it is to wrap WCF calls (inside a client proxy) to avoid the same boiler plate code.
private void InvokeAndHandleFaults(
Action<Data, Context> wcfCall,
Data data,
Context context)
{
bool isSuccess = false;
try
{
wcfCall(data, context);
if (this.ChannelFactory.State != System.ServiceModel.CommunicationState.Faulted)
{
this.ChannelFactory.Close();
}
isSuccess = true;
}
catch (FaultException ex)
{
HandleFault(ex);
}
finally
{
if (!isSuccess)
{
this.ChannelFactory.Abort();
}
}
}
In terms of the example in the question, I would probably not use an Action. I would definitely not refactor to use an Action. Mainly because the actual logic is quite simple so I don't see much benefit. As the "complexity"/size of the repeated code increased I would be more likely to use a delegate.