【電子合本版】Code Complete 第2版 完全なプログラミングを目指して
目次
はじめに
プログラミングをしていると、
リソースを使った時に、
処理が終わったり、処理中に例外が発生しても、
必ずリソースをクローズしたい
いう処理をよく実装すると思います。
このような処理を
Auto resource management
と呼ぶらしいのですが、
多くのプログラミング言語は、
言語の機能として、
このような仕組みを簡単に実装する機能を提供しています。
そこで、今回は
各プログラミング言語で
Auto resource managementを実装する方法をまとめておきたいと思います。
Python
Pythonでは、Auto resource managementを実現するコードを
コンテキストマネージャと呼びます。
コンテキストマネージャは、下記のコードのように
__enter__
と__exit__
関数を実装したクラスを準備して、
with文と一緒に使うと、withに入った時に__enter__
関数を実行し、
出た時に、__exit__
関数を実行してくれます。
withのasの部分は、__enter__
関数の返り値が入ります。
class MyContextManager: def __enter__(self): print('enter') return "yield" def __exit__(self, exc_type, exc_value, traceback): print('enter') def main(): with MyContextManager() as e: print(f'hello context manager:{e}') if __name__ == '__main__': # === Output === # enter # hello context manager:yield # exit main()
また、公式ライブラリのcontextlib
のcontextmanager
を使うと、
yeild文と組み合わせて、
簡単にAuto resource managementが実現できます。
from contextlib import contextmanager @contextmanager def context_manager_sample(): print('enter') yield "yield" print('exit') def main(): with context_manager_sample() as e: print(f'hello context manager:{e}') if __name__ == '__main__': # === Output === # enter # hello context manager:yield # exit main()
Java
Javaでは、Java8から導入されたtry-with-resourcesを使うことで、
簡単にAuto resource managementを実現できます。
下記のような、AutoClosableやClosableをimplementし、
コンストラクタでリソースを開く時の実装をし、
closeで、リソースを閉じる処理を実装します。
import java.lang.AutoCloseable; public class AutoResource implements AutoCloseable { public static AutoResource setUpAutoLock(){ return new AutoResource(); } private AutoResource(){ System.out.println("enter"); } @Override public void close() { System.out.println("exit"); } }
あとは、下記のようにtry-with-resource構文を使って、
Auto resource managementを実現できます。
try (AutoResource _lock = setUpAutoLock()){ System.out.println("aaa"); }
また、下記にように、複数のリソースをまとめて管理することも可能です。
try (Socket soc server.accept(); var isr = new InputStreamReader(soc.getInputStream()); var bur = new BufferedReader(isr); var w = PrintWriter(soc.getOutputStream() ){ .... }
C++
C++の場合は、デストラクタがあるので、
リソースのOpen - Closeの関数を、コンストラクタとデストラクタで定義し、
ローカル変数としてクラスをインスタンス化しておけば、
ローカル変数が破棄される時に、簡単にAuto resource managementできます。
そもそもC++には言語的にはfinallyが無いのですが、
下記の記事のように、テンプレートを使って、
finallyのような機能を実装することもできます。
Julia
Juliaは、finalizer
を使うことで、あるオブジェクトがgcかかった時に、
呼ぶ関数を指定することができます。
これを使うことで、Auto resource managementを実現できそうですが、
ただこの方法はあまり推奨されていないようです。
また、前述のPythonと同様に、Juliaもwith文があるのですが、
それをAuto resource managementに使えるように、
議論が続いていますが、まだ結論は出ていないようです。
現時点では、try_catch_finallyを使うのが良さそうです。
参考資料
【電子合本版】Code Complete 第2版 完全なプログラミングを目指して
MyEnigma Supporters
もしこの記事が参考になり、
ブログをサポートしたいと思われた方は、
こちらからよろしくお願いします。