Add finally
method for deferred execution
This commit is contained in:
parent
db1abbec4c
commit
1bf8e57943
@ -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];
|
||||
|
88
src/libcore/private/finally.rs
Normal file
88
src/libcore/private/finally.rs
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user