プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
Ruby1.9、Proc.newとprocとlambdaの違い
ブロック付きメソッドをクロージャで実行する場合、

  #クロージャで実行(1)
  a = Proc.new{ブロック}
  #呼出
  a.call(param)
  
  #クロージャで実行(2)
  b = proc{ブロック}
  #呼出
  b.call(param)
  
  #クロージャで実行(3)
  c = lambda{ブロック}
  #呼出
  c.call(param)


ってなやり方があるわけですが
Proc.newとprocとlambdaはどれ使っても同じなの(--?
ってのが調べたきっかけです。

結果、なんか微妙に違うみたいですね(--ゞ
こんな感じφ(--)

1.引数の扱いの違い
 「Proc.new」と「proc」は引数の数が合わなくてもOK。
 「lambda」は引数の数が合わないとエラー

 こんなコードを書くとφ(--)

  #Proc.new
  a = Proc.new{|x,y| 
                  if x.nil?
                      print "x.nil"
                  else
                      print x
                  end
                  print ":"
                  if y.nil?
                      print "y.nil"
                  else
                      print y
                  end
                  puts ":Proc.new end"
              }
  
  #足りない引数はnil扱い
  a.call(1)
  #引数の数が一致
  a.call(1,2)
  #引数の数が多い分には無視
  a.call(1,2,3)
  
  b = proc{|x2,y2| 
                  if x2.nil?
                      print "x2.nil"
                  else
                      print x2
                  end
                  print ":"
                  if y2.nil?
                      print "y2.nil"
                  else
                      print y2
                  end
                  puts ":proc end"
              }
  #足りない引数はnil扱い
  b.call(11)
  #引数の数が一致
  b.call(11,12)
  #引数の数が多い分には無視
  b.call(11,12,13)
  
  c = lambda{|x3,y3| 
                  if x3.nil?
                      print "x3.nil"
                  else
                      print x3
                  end
                  print ":"
                  if y3.nil?
                      print "y3.nil"
                  else
                      print y3
                  end
                  puts ":lambda end"
              }
  #引数の数が合わないとエラー
  #c.call(111)
  #引数の数が一致
  c.call(111,112)
  #引数の数が合わないとエラー
  #c.call(111,112,113)


 こんな結果になりますφ(--)

  1:y.nil:Proc.new end
  1:2:Proc.new end
  1:2:Proc.new end
  11:y2.nil:proc end
  11:12:proc end
  11:12:proc end
  111:112:lambda end


2.return時の挙動
 「Proc.new」と「proc」はメソッドから抜ける
 「lambda」はブロックから抜ける
 要は「Proc.new」と「proc」は
 「.call()」した部分のコードが書き換わるイメージ
 「lambda」は「.call()」した部分からブロックを
 サブルーチンとして呼び出すイメージってわけですな。

 こんなコードを書くとφ(--)

  class HogeClass
      #Proc.new
      def hogeMethod1
          puts "hogeMethod1:start"
          a = Proc.new{
                  puts "1"
                  return "a"
              }
          p a.call
          #ここから下は処理されない
          puts "2"
          return "b"
      end
  
      #proc
      def hogeMethod2
          puts "hogeMethod2:start"
          b = proc{
                  puts "3"
                  return "c"
              }
          p b.call
          #ここから下は処理されない
          puts "4"
          return "d"
      end
  
      #proc
      def hogeMethod3
          puts "hogeMethod3:start"
          c = lambda{
                  puts "5"
                  return "e"
              }
          p c.call
          puts "6"
          return "f"
      end
  end
  
  aaa = HogeClass.new
  p aaa.hogeMethod1
  p aaa.hogeMethod2
  p aaa.hogeMethod3


 こんな結果になりますφ(--)

  hogeMethod1:start
  1
  "a"
  hogeMethod2:start
  3
  "c"
  hogeMethod3:start
  5
  "e"
  6
  "f"


3.break時の挙動
 「Proc.new」と「proc」はエラーになる
 「lambda」はブロックから抜ける
 使う機会は殆ど無いと思いますけどね
 使いどころが分からん知識です。

 こんなコードを書くとφ(--)

  class HogeClass
      #Proc.new
      def hogeMethod1
          puts "hogeMethod1:start"
          i = 0
          while i < 5
              i += 1
              puts i
  
              if i == 3
                  a = Proc.new{
                          break;
                      }
                  a.call
              end
          end
      end
  
      #proc
      def hogeMethod2
          puts "hogeMethod2:start"
          i = 0
          while i < 5
              i += 1
              puts i
  
              if i == 3
                  b = proc{
                          break;
                      }
                  b.call
              end
          end
      end
  
      #proc
      def hogeMethod3
          puts "hogeMethod3:start"
          i = 0
          while i < 5
              i += 1
              puts i
  
              if i == 3
                  #ブロックから抜けるだけなのでループは続く
                  c = lambda{
                          break;
                      }
                  c.call
              end
          end
      end
  end
  
  aaa = HogeClass.new
  #エラーになる
  #aaa.hogeMethod1
  #エラーになる
  #aaa.hogeMethod2
  aaa.hogeMethod3


 こんな結果になりますφ(--)

  hogeMethod3:start
  1
  2
  3
  4
  5

 抜けるのはあくまでブロックだから
 ループは最後まで回っちゃってる感じ(--)b
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● Ruby  thema:パソコンな日々 - genre:コンピュータ  Posted by ササキマコト 

  関連記事