クロージャ とは
Wikipedia で「クロージャ」を見てみます。
クロージャ(クロージャー、英語: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。いくつかの言語ではラムダ式や無名関数にて利用可能な機能・概念である。引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決することを特徴とする。関数とそれを評価する環境のペアであるともいえる。
何を言っているのかさっぱり分かりません*1。具体的にコードを書いて理解をしてみました。言語は Ruby です。
Ruby で クロージャ を実装する
Proc オブジェクトを用います。Proc オブジェクトとは、ブロックをオブジェクト化したものです。詳細は別に譲ります。
クロージャを実装するので、「戻り値が Proc オブジェクト であるメソッド(関数)」を作ることが必須となります。そのメソッド(関数)を適当な変数に代入し、戻り値である Proc オブジェクト を、 call
メソッドを用いて実行する、という流れです。
その前提のもと、以下に「クロージャにならない例」と「クロージャになる例」を順に書きます。
クロージャにならない例
クロージャにならない例です。
def this_is_not_closure Proc.new do i = 0 i += 1 end end
上記のように定義した this_is_not_closure
をクロージャであると仮定して、実行してみます。
foobar = this_is_not_closure foobar.call #=> 1 foobar.call #=> 1 foobar.call #=> 1
クロージャになってません😅
クロージャになる例
クロージャになる例です。
def this_is_closure i = 0 Proc.new do i += 1 end end
上記のように定義した this_is_closure
をクロージャであると仮定して、実行してみます。
foobar = this_is_closure foobar.call #=> 1 foobar.call #=> 2 foobar.call #=> 3
無事クロージャになりました😀
考察
クロージャの作り方としては上記のように書けばよいです。が、クロージャは、(少なくとも私は)とても技巧的な書き方だと思いますし*2、同様の機能を持たせるための書き方はたいてい他にもあり、そちらの書き方の方が可読性が高いと思っています。
となると疑問としては「なぜクロージャを使うのか」ということになります。
その点については記事にまとめてくださった方がいらっしゃり、分かりやすいので参考にしてみてください。変数のスコープの性質上、JavaScript で用いられることにやはり意義が高そうです。
参考
「プロを目指す人のためのRuby入門」を参考にしました。名著です。