diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-01-15 17:11:16 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-01-17 19:24:52 -0800 |
| commit | 1bf8e579436941a82e4a4806b74dfd27ed4d1d74 (patch) | |
| tree | 8a469ef891d85cee00e71f520de12f6d46e5918f | |
| parent | db1abbec4ca9f18a224441c483cf23bb4f8361fd (diff) | |
| download | rust-1bf8e579436941a82e4a4806b74dfd27ed4d1d74.tar.gz rust-1bf8e579436941a82e4a4806b74dfd27ed4d1d74.zip | |
Add `finally` method for deferred execution
| -rw-r--r-- | src/libcore/private.rs | 2 | ||||
| -rw-r--r-- | src/libcore/private/finally.rs | 88 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/libcore/private.rs b/src/libcore/private.rs index ef25cb52e8b..3eadce1c30c 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -32,6 +32,8 @@ use uint; pub mod at_exit; #[path = "private/global.rs"] pub mod global; +#[path = "private/finally.rs"] +pub mod finally; extern mod rustrt { #[legacy_exports]; diff --git a/src/libcore/private/finally.rs b/src/libcore/private/finally.rs new file mode 100644 index 00000000000..f4d76dfd54d --- /dev/null +++ b/src/libcore/private/finally.rs @@ -0,0 +1,88 @@ +/*! +The Finally trait provides a method, `finally` on +stack closures that emulates Java-style try/finally blocks. + +# Example + +~~~ +do || { + ... +}.finally { + alway_run_this(); +} +~~~ +*/ + +use ops::Drop; +use task::{spawn, failing}; + +pub trait Finally<T> { + fn finally(&self, +dtor: &fn()) -> T; +} + +impl<T> &fn() -> T: Finally<T> { + // XXX: Should not require a mode here + fn finally(&self, +dtor: &fn()) -> T { + let _d = Finallyalizer { + dtor: dtor + }; + + (*self)() + } +} + +struct Finallyalizer { + dtor: &fn() +} + +impl Finallyalizer: Drop { + fn finalize(&self) { + (self.dtor)(); + } +} + +#[test] +fn test_success() { + let mut i = 0; + do (|| { + i = 10; + }).finally { + assert !failing(); + assert i == 10; + i = 20; + } + assert i == 20; +} + +#[test] +#[ignore(cfg(windows))] +#[should_fail] +fn test_fail() { + let mut i = 0; + do (|| { + i = 10; + fail; + }).finally { + assert failing(); + assert i == 10; + } +} + +#[test] +fn test_retval() { + let i = do (fn&() -> int { + 10 + }).finally { }; + assert i == 10; +} + +#[test] +fn test_compact() { + // XXX Should be able to use a fn item instead + // of a closure for do_some_fallible_work, + // but it's a type error. + let do_some_fallible_work: &fn() = || { }; + fn but_always_run_this_function() { } + do_some_fallible_work.finally( + but_always_run_this_function); +} \ No newline at end of file |
