Index: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/mrblib/proc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrblib/proc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/mrblib/proc.rb	(revision 439)
@@ -28,5 +28,5 @@
     pproc = self
     make_curry = proc do |given_args=[]|
-      send(type) do |*args|
+      __send__(type) do |*args|
         new_args = given_args + args
         if new_args.size >= arity
@@ -40,3 +40,11 @@
   end
 
+  def <<(other)
+    ->(*args, &block) { call(other.call(*args, &block)) }
+  end
+
+  def >>(other)
+    ->(*args, &block) { other.call(call(*args, &block)) }
+  end
+
 end
Index: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/src/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/src/proc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/src/proc.c	(revision 439)
@@ -26,6 +26,6 @@
     const char *filename;
 
-    filename = mrb_debug_get_filename(irep, 0);
-    line = mrb_debug_get_line(irep, 0);
+    filename = mrb_debug_get_filename(mrb, irep, 0);
+    line = mrb_debug_get_line(mrb, irep, 0);
 
     return (!filename && line == -1)? mrb_nil_value()
@@ -39,5 +39,5 @@
   struct RProc *p = mrb_proc_ptr(self);
   mrb_value str = mrb_str_new_lit(mrb, "#<Proc:");
-  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
+  mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
 
   if (!MRB_PROC_CFUNC_P(p)) {
@@ -47,11 +47,11 @@
     mrb_str_cat_lit(mrb, str, "@");
 
-    filename = mrb_debug_get_filename(irep, 0);
+    filename = mrb_debug_get_filename(mrb, irep, 0);
     mrb_str_cat_cstr(mrb, str, filename ? filename : "-");
     mrb_str_cat_lit(mrb, str, ":");
 
-    line = mrb_debug_get_line(irep, 0);
+    line = mrb_debug_get_line(mrb, irep, 0);
     if (line != -1) {
-      str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line));
+      mrb_str_concat(mrb, str, mrb_fixnum_value(line));
     }
     else {
@@ -73,8 +73,5 @@
   mrb_value blk;
 
-  mrb_get_args(mrb, "&", &blk);
-  if (mrb_nil_p(blk)) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
-  }
+  mrb_get_args(mrb, "&!", &blk);
 
   return blk;
@@ -95,19 +92,21 @@
 {
   struct parameters_type {
+    size_t len;
+    const char *name;
     int size;
-    const char *name;
   } *p, parameters_list [] = {
-    {0, "req"},
-    {0, "opt"},
-    {0, "rest"},
-    {0, "req"},
-    {0, "block"},
-    {0, NULL}
+    {sizeof("req")   - 1, "req",   0},
+    {sizeof("opt")   - 1, "opt",   0},
+    {sizeof("rest")  - 1, "rest",  0},
+    {sizeof("req")   - 1, "req",   0},
+    {sizeof("block") - 1, "block", 0},
+    {0, NULL, 0}
   };
   const struct RProc *proc = mrb_proc_ptr(self);
   const struct mrb_irep *irep = proc->body.irep;
   mrb_aspec aspec;
-  mrb_value sname, parameters;
+  mrb_value parameters;
   int i, j;
+  int max = -1;
 
   if (MRB_PROC_CFUNC_P(proc)) {
@@ -121,14 +120,16 @@
     return mrb_ary_new(mrb);
   }
-  if (GET_OPCODE(*irep->iseq) != OP_ENTER) {
+  if (*irep->iseq != OP_ENTER) {
     return mrb_ary_new(mrb);
   }
 
   if (!MRB_PROC_STRICT_P(proc)) {
+    parameters_list[0].len = sizeof("opt") - 1;
     parameters_list[0].name = "opt";
+    parameters_list[3].len = sizeof("opt") - 1;
     parameters_list[3].name = "opt";
   }
 
-  aspec = GETARG_Ax(*irep->iseq);
+  aspec = PEEK_W(irep->iseq+1);
   parameters_list[0].size = MRB_ASPEC_REQ(aspec);
   parameters_list[1].size = MRB_ASPEC_OPT(aspec);
@@ -139,12 +140,23 @@
   parameters = mrb_ary_new_capa(mrb, irep->nlocals-1);
 
+  max = irep->nlocals-1;
   for (i = 0, p = parameters_list; p->name; p++) {
-    if (p->size <= 0) continue;
-    sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name));
+    mrb_value sname = mrb_symbol_value(mrb_intern_static(mrb, p->name, p->len));
+
     for (j = 0; j < p->size; i++, j++) {
-      mrb_value a = mrb_ary_new(mrb);
+      mrb_value a;
+
+      a = mrb_ary_new(mrb);
       mrb_ary_push(mrb, a, sname);
-      if (irep->lv[i].name) {
-        mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i].name));
+      if (i < max && irep->lv[i].name) {
+        mrb_sym sym = irep->lv[i].name;
+        const char *name = mrb_sym_name(mrb, sym);
+        switch (name[0]) {
+        case '*': case '&':
+          break;
+        default:
+          mrb_ary_push(mrb, a, mrb_symbol_value(sym));
+          break;
+        }
       }
       mrb_ary_push(mrb, parameters, a);
@@ -164,6 +176,6 @@
   mrb_define_method(mrb, p, "parameters",      mrb_proc_parameters,      MRB_ARGS_NONE());
 
-  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE());
-  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
+  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
 }
 
Index: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.c	(revision 439)
@@ -14,8 +14,11 @@
   mrb_sym n;
   mrb_value n_val;
+  mrb_method_t m;
+  struct RProc *p;
   mrb_get_args(mrb, "n", &n);
   n_val = mrb_symbol_value(n);
-  mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
-                        mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val));
+  p = mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val);
+  MRB_METHOD_FROM_PROC(m, p);
+  mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m);
   return self;
 }
@@ -34,7 +37,10 @@
   mrb_sym n;
   mrb_value *argv; mrb_int argc;
+  mrb_method_t m;
+  struct RProc *p;
   mrb_get_args(mrb, "na", &n, &argv, &argc);
-  mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
-                        mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv));
+  p = mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv);
+  MRB_METHOD_FROM_PROC(m, p);
+  mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m);
   return self;
 }
Index: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.rb	(revision 439)
@@ -2,14 +2,35 @@
 # Proc(Ext) Test
 
+def enable_debug_info?
+  return @enable_debug_info unless @enable_debug_info == nil
+  begin
+    raise
+  rescue => e
+    @enable_debug_info = !e.backtrace.empty?
+  end
+end
+
 assert('Proc#source_location') do
-  loc = Proc.new {}.source_location
-  next true if loc.nil?
-  assert_equal loc[0][-7, 7], 'proc.rb'
-  assert_equal loc[1], 5
+  skip unless enable_debug_info?
+  file, line = Proc.new{}.source_location
+  assert_equal __FILE__, file
+  assert_equal __LINE__ - 2, line
 end
 
 assert('Proc#inspect') do
   ins = Proc.new{}.inspect
-  assert_kind_of String, ins
+  if enable_debug_info?
+    metas = %w(\\ * ? [ ] { })
+    file = __FILE__.split("").map{|c| metas.include?(c) ? "\\#{c}" : c}.join
+    line = __LINE__ - 4
+  else
+    file = line = "-"
+  end
+  assert_match "#<Proc:0x*@#{file}:#{line}>", ins
+end
+
+assert('Proc#parameters') do
+  parameters = Proc.new{|x,y=42,*other|}.parameters
+  assert_equal [[:opt, :x], [:opt, :y], [:rest, :other]], parameters
 end
 
@@ -67,4 +88,21 @@
 assert('Kernel#proc') do
   assert_true !proc{|a|}.lambda?
+
+  assert_raise LocalJumpError do
+    proc{ break }.call
+  end
+end
+
+assert "Proc#<< and Proc#>>" do
+  add3 = ->(n) { n + 3 }
+  mul2 = ->(n) { n * 2 }
+
+  f1 = mul2 << add3
+  assert_kind_of Proc, f1
+  assert_equal 16, f1.call(5)
+
+  f2 = mul2 >> add3
+  assert_kind_of Proc, f2
+  assert_equal 13, f2.call(5)
 end
 
