2016-08-24 25 views
0

私はスコープの問題を理解しようとしています。私は、AWS上に関連リソースの束を設定している手続き関数を持っています。私は失敗をキャッチし、設定されているすべての関係をロールバックする必要があります。私はtryキャッチ設定をしていますが、tryブロック内の変数はキャッチでは使用できませんので、ロールバックするための正しい手順を取ることができます。Elixir Try Catch

try do 
    c = connection 
    cert = aws.cert 
    module = aws.create_mod(cert) 
    etc... 
rescue 
    :error -> 
     rollback(c, cert, module) 
end 

これを処理する方法についてのアドバイスはありますか?

+0

真剣に - これはgen_server経由で行います。プロセス内のリソースをスピンアップします。 –

答えて

1

これは、Elixirが例外が発生するまでにこれらの変数が設定されることを保証できないためです。これはあなたの場合ではないかもしれませんが、このようなものを想像してください。

try do 
    foo = do_something_safe() 
    bar = do_something_that_will_raise_an_error() 
    baz = do_something_else_safe() 
    ... 
rescue 
    RuntimeError -> 
    quux(foo, baz) 
end 

上記の例では、do_something_that_will_raise_an_error()を呼び出すとエラーが発生します。 barbazの両方が設定されていません。

この特定のケースでは、あなたがdo_something_that_will_raise_an_error()への呼び出しにエラーが発生した場合でも、今

baz = do_something_else_safe() 
foo = do_something_safe() 
try do 
    bar = do_something_that_will_raise_an_error() 
    ... 
rescue 
    RuntimeError -> 
    quux(foo, baz) 
end 

ような何かを行うことができるかもしれません、あなたはまだfooを持っている、とbaz変数が設定されており、彼らができますレスキューブロックで使用することができます。

基本的には、try以外の変数を設定してください。 Thisは、try ... rescueの可変スコープの概要を少ししか示していません。

これを念頭に置いて、スーパーバイザーをセットアップして、GenServer(または実際に監督された他のプロセス)の内部でこれを行う方がよい場合があります。そうすれば、それがクラッシュした場合、監督者はそれをどうするかを決めることができます。 ElixirとErlangの両方が、防御的にプログラムしようとするのではなく、「クラッシュさせる」という考え方のものです。