Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger a function once, and only once...?

I often want to trigger a certain function just once, but I need to trigger it from within another function that gets repeatedly called. For instance, taking a snapshot of something for later use. I usually do it by setting a global boolean.

I'm wondering whether the way I do it is actually best way?

I seem to recall reading that global variables are bad, and global boolean variables are even worse!

Anyway, this is how I usually accomplish triggering a certain method just once:

In my initial set of variables...

private var myStatus:Boolean = false;

Then, within the function that gets called often...

if (!myStatus) {
    doMyFunction();
    myStatus = true;
}

It seems fairly logical to me, but is it the right thing?

UPDATE: Well, based on what I learned from your answers, instead of checking a global boolean variable, I now first check whether the XML node exists (I am storing the images within an XML structure before any writing to disk occurs), and, if it doesn't, then I append a new node with the base64 encoded image data. I do still set a boolean flag so that later on I can overwrite the blank image with user edited image data if need be. It works perfectly. Thank you all for your help!

I also now feel more comfortable about using that particular (thread unsafe) system in certain situations.

like image 576
defmeta Avatar asked Dec 09 '08 22:12

defmeta


2 Answers

When you call a function it should do what you expect it to do with the arguments you give it. If you call a function twice in exactly the same way you should expect that function to give you the same results or do the same thing.

It is probably better to move this call-once dependency to the logic that calls your function many times. If you only need to call the function once then only call it once. Alternatively, pass different arguments to the function to indicate that you're doing something different.

like image 87
rojoca Avatar answered Sep 19 '22 03:09

rojoca


It really depends on precisely what you mean. If your code will be invoked from more than one thread, then you have a race condition which could mean that doMyFunction could be called many times. This is because more than one thread could check myStatus, see that it is false, then invoke doMyFunction. You can improve the situation a little bit by setting the variable first:

if (!myStatus) {
    myStatus = true;
    doMyFunction();
}

but that only narrows the window for problems, doesn't eliminate it.

To eliminate the race condition, you need a lock.

like image 45
Ned Batchelder Avatar answered Sep 19 '22 03:09

Ned Batchelder