mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* vm_eval.c (vm_call0): should pass block to enumerators. patched
by Kazuki Tsujimoto. [ruby-dev:44961][Bug #5731] * vm_eval.c (method_missing), vm_insnhelper.c (vm_call_method): ditto. patched by satoshi shiba. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34399 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									cba57022b0
								
							
						
					
					
						commit
						72969cd348
					
				
					 4 changed files with 63 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
Mon Jan 30 19:08:19 2012  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* vm_eval.c (vm_call0): should pass block to enumerators.  patched
 | 
			
		||||
	  by Kazuki Tsujimoto.  [ruby-dev:44961][Bug #5731]
 | 
			
		||||
 | 
			
		||||
	* vm_eval.c (method_missing), vm_insnhelper.c (vm_call_method):
 | 
			
		||||
	  ditto.  patched by satoshi shiba.
 | 
			
		||||
 | 
			
		||||
Mon Jan 30 12:31:05 2012  NAKAMURA Usaku  <usa@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* file.c (append_fspath): need to set the encoding to result always.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -446,6 +446,57 @@ class TestObject < Test::Unit::TestCase
 | 
			
		|||
    assert_equal([[:respond_to?, :to_ary, true]], called, bug5158)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_method_missing_passed_block
 | 
			
		||||
    bug5731 = '[ruby-dev:44961]'
 | 
			
		||||
 | 
			
		||||
    c = Class.new do
 | 
			
		||||
      def method_missing(meth, *args) yield(meth, *args) end
 | 
			
		||||
    end
 | 
			
		||||
    a = c.new
 | 
			
		||||
    result = nil
 | 
			
		||||
    assert_nothing_raised(LocalJumpError, bug5731) do
 | 
			
		||||
      a.foo {|x| result = x}
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
    result = nil
 | 
			
		||||
    e = a.enum_for(:foo)
 | 
			
		||||
    assert_nothing_raised(LocalJumpError, bug5731) do
 | 
			
		||||
      e.each {|x| result = x}
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
 | 
			
		||||
    c = Class.new do
 | 
			
		||||
      def respond_to_missing?(id, priv)
 | 
			
		||||
        true
 | 
			
		||||
      end
 | 
			
		||||
      def method_missing(id, *args, &block)
 | 
			
		||||
        return block.call(:foo, *args)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    foo = c.new
 | 
			
		||||
 | 
			
		||||
    result = nil
 | 
			
		||||
    assert_nothing_raised(LocalJumpError, bug5731) do
 | 
			
		||||
      foo.foobar {|x| result = x}
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
    result = nil
 | 
			
		||||
    assert_nothing_raised(LocalJumpError, bug5731) do
 | 
			
		||||
      foo.enum_for(:foobar).each {|x| result = x}
 | 
			
		||||
    end
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
 | 
			
		||||
    result = nil
 | 
			
		||||
    foobar = foo.method(:foobar)
 | 
			
		||||
    foobar.call {|x| result = x}
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
 | 
			
		||||
    result = nil
 | 
			
		||||
    foobar = foo.method(:foobar)
 | 
			
		||||
    foobar.enum_for(:call).each {|x| result = x}
 | 
			
		||||
    assert_equal(:foo, result, bug5731)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_send_with_no_arguments
 | 
			
		||||
    assert_raise(ArgumentError) { 1.send }
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,6 +118,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
 | 
			
		|||
 | 
			
		||||
	RB_GC_GUARD(new_args);
 | 
			
		||||
	rb_ary_unshift(new_args, ID2SYM(id));
 | 
			
		||||
	th->passed_block = blockptr;
 | 
			
		||||
	return rb_funcall2(recv, idMethodMissing,
 | 
			
		||||
			   argc+1, RARRAY_PTR(new_args));
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -563,6 +564,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
 | 
			
		|||
{
 | 
			
		||||
    VALUE *nargv, result, argv_ary = 0;
 | 
			
		||||
    rb_thread_t *th = GET_THREAD();
 | 
			
		||||
    const rb_block_t *blockptr = th->passed_block;
 | 
			
		||||
 | 
			
		||||
    th->method_missing_reason = call_status;
 | 
			
		||||
    th->passed_block = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -589,6 +591,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
 | 
			
		|||
    if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
 | 
			
		||||
	raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
 | 
			
		||||
    }
 | 
			
		||||
    th->passed_block = blockptr;
 | 
			
		||||
    result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
 | 
			
		||||
    if (argv_ary) rb_ary_clear(argv_ary);
 | 
			
		||||
    return result;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -599,6 +599,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
 | 
			
		|||
		argv[0] = ID2SYM(me->def->original_id);
 | 
			
		||||
		MEMCPY(argv+1, cfp->sp - num, VALUE, num);
 | 
			
		||||
		cfp->sp += - num - 1;
 | 
			
		||||
		th->passed_block = blockptr;
 | 
			
		||||
		val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv);
 | 
			
		||||
		break;
 | 
			
		||||
	      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue