パスワードを忘れた? アカウント作成
286431 journal

t-nissieの日記: 【電脳】クロージャ (closure) ってモノを勉強してみる 5

日記 by t-nissie

WEB+DB PRESS Vol.60
西尾泰和著
特集1
言語の核を知れば,自ずと作法が見えてくる
プログラマが知るべき言語設計の基礎知識
でクロージャ (closure) ってモノを勉強してみる

スコープとオブジェクトの概念に関連して重要らしいけど
ありがたみがいまいちわからなかった

JavaScriptで書くとこんなかんじ
counter.htmlをFirefox+Firebugで開くと実行される
JavaScriptってのはそのまま実行できないのか?
counter.html:

<script type="text/javascript">
  <!--
      function makeCounter()
      {
        var count = 0;
        function push()
        {
          count++;
          console.log(count);
        }
        return push;   //関数を返している
      }
      c1 = makeCounter();   //cには関数が代入される
      c1();
      c1();
      c1();
      c2 = makeCounter();
      c2();
      c2();
      //-->
</script>

Rubyで書くとこんなかんじ
counter.rb

def makeCounter
  count = 0
  f = lambda{
    count += 1
    puts count
  }
  return f
end
c1 = makeCounter
c1.call()
c1.call()
c1.call()
c2 = makeCounter
c2.call()
c2.call()

『「クロージャは廉価版のオブジェクトだ。オブジェクトは廉価版の
クロージャだ。」と言われることがあります。』って書いてあるけど、
そんなことは言われないような気がするし、後者は「高価版」?
構造体とかクラスでこう書けるってこと?
counter-class.rb

class Counter
  def initialize
    @count = 0
  end
  def up
    @count += 1
    puts @count
  end
end
c1 = Counter.new
c1.up()
c1.up()
c1.up()
c2 =  Counter.new
c2.up()
c2.up()

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by Anonymous Coward on 2010年12月29日 22時25分 (#1881614)
    関数を引数に取る関数を使うときにクロージャーがあると便利。

    例えば、任意の関数で比較して、ソートを行う関数があるときに、「xとの差の絶対値でソート」したい場合。クロージャーが無いと、どこからでも参照可能な変数にxの値を入れておく必要がありますが、クロージャーがあるとクロージャーからしかアクセスできない変数にxの値を持たせることができます。

    高階関数が普通の言語だと、処理を変えたいときに引数として渡す関数を変えるだけで済ませたいので、余計な引数を省こうとすると、クロージャーの出番。
  • by Anonymous Coward on 2010年12月29日 23時19分 (#1881629)

    Windowsなら「cscript hoge.js」とかやれば直接実行できますよ。
    もちろんブラウザのDOMがないのでconsole.log等は適切に置き換える必要があります。
    FirefoxのスクリプトエンジンであるSpiderMonkeyも単体で実行可能ですが、どうも自分でビルドする必要があるみたいなのでちょっと手軽とは言いかねますね。

    • mozilla/Java な Rhino - MDC Doc Center [mozilla.org] を使うというのはどうでしょう。

      あと、自分はクロージャは「状態とかを引数でもらう(とは限らないか)ことで関数オブジェクト(単機能のクラスインスタンスと捉えればだいたいいいんじゃないかな)が取得できる機能」みたいに理解してます。
      # 変数アクセスも大きいとは思いますが

      即席で関数オブジェクトが作れるという意味ではラムダ式も似たようなものですが、そこにテンプレート風味に元の関数を利用しつつ個別の関数オブジェクトが作れるのが良いところでしょうか。

      良い意味で中途半端なので、一言ではいいにくいですね。

      別コメにもある関数オブジェクトを引数にとる関数が中で使うクロージャとかはかなり柔軟ですしね...

      --
      M-FalconSky (暑いか寒い)
      親コメント
  • by Anonymous Coward on 2011年04月01日 21時03分 (#1929317)

    http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html [mit.edu]
    "objects are a poor man's closures" and "closures are a poor man's objects"

typodupeerror

あと、僕は馬鹿なことをするのは嫌いですよ (わざとやるとき以外は)。-- Larry Wall

読み込み中...