I have known about this particular hammer for ten years. It is a technique widely used in
Melati, as William was mostly 'translating on the fly from OCAML' at the time, however I have never recognised a situation where it was the correct approach.
To a commercial programmer on the long journey from BASIC to lisp, via perl and java, even when you know of the
functional hammer the world does not appear to have any
functional nails in it.
Last night I did recognise such a situation. I wanted to reuse a bit of code:
if (lock()) {
try {
body();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
unlock();
}
} else {
throw new RuntimeException("Lock file " + LOCK_FILE_NAME + " exists.");
}
The only way to reuse this, for a
body2() function, would have been to cut'n'paste, which I will go to some lengths to avoid.
I extracted this to its own abstract class
ExclusiveFunction
import java.io.File;
import java.io.IOException;
/**
* @author timp
* @since 2011/06/07 22:00:01
*
*/
public abstract class ExclusiveFunction {
final static String LOCK_FILE_NAME = "/tmp/EXCLUSIVE_LOCK";
abstract void body() throws Exception;
public void invoke() {
if (lock()) {
try {
body();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
unlock();
}
} else {
throw new RuntimeException("Lock file " + LOCK_FILE_NAME + " exists.");
}
}
private boolean lock() {
File lockFile = new File(LOCK_FILE_NAME);
if (!lockFile.exists()) {
try {
lockFile.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
return true;
}
return false;
}
private void unlock() {
new File(LOCK_FILE_NAME).delete();
}
}
which is then invoked with:
new ExclusiveFunction() {
@Override
void body() throws IOException {
body2();
}
}.invoke();
I think the world is soon going to appear to have a lot more nails in it.