diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-08 23:24:29 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-08-08 23:24:29 +0000 |
commit | 09d57b8e0c3bb80d43798d7a2bfc239229126e9a (patch) | |
tree | d8b00e5170b80d83851bd7013a4a27123efb0da7 | |
parent | 81579af43e3ad506e30a81bda710570d78dea021 (diff) | |
download | ruby-09d57b8e0c3bb80d43798d7a2bfc239229126e9a.tar.gz |
* parse.y (f_block_arg), eval.c (rb_yield_0): deal with dynamic
variable lambda arguments. [ruby-core:05540]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8955 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | eval.c | 14 | ||||
-rw-r--r-- | parse.y | 2 | ||||
-rw-r--r-- | test/ruby/test_lambda.rb | 53 |
4 files changed, 66 insertions, 8 deletions
@@ -1,3 +1,8 @@ +Tue Aug 9 08:24:05 2005 Mauricio Fernandez <mfp@acm.org> + + * parse.y (f_block_arg), eval.c (rb_yield_0): deal with dynamic + variable lambda arguments. [ruby-core:05540] + Mon Aug 8 22:13:48 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * eval.c (assign): deal with new block argument. @@ -4893,6 +4893,13 @@ rb_yield_0(val, self, klass, flags, avalue) } formal_assign(self, var, RARRAY(val)->len, RARRAY(val)->ptr, 0); } + else if (nd_type(var) == NODE_BLOCK) { + if (var->nd_next) { + bvar = var->nd_next->nd_head; + } + var = var->nd_head; + goto block_var; + } else { int len = 0; if (avalue) { @@ -5269,13 +5276,6 @@ assign(self, lhs, val, pcall) } break; - case NODE_BLOCK: - lhs = lhs->nd_head; - if (nd_type(lhs) == NODE_ARGS) { - formal_assign(self, lhs, 1, &val, 0); - break; - } - default: rb_bug("bug in variable assignment"); break; @@ -4192,7 +4192,7 @@ f_block_arg : blkarg_mark tIDENTIFIER yyerror("block argument must be local variable"); else if (!dyna_in_block() && local_id($2)) yyerror("duplicated block argument name"); - $$ = NEW_BLOCK_ARG($2); + $$ = dyna_in_block() ? assignable($2, 0) : NEW_BLOCK_ARG($2); /*% $$ = $2; %*/ diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb new file mode 100644 index 0000000000..0173bead11 --- /dev/null +++ b/test/ruby/test_lambda.rb @@ -0,0 +1,53 @@ +require 'test/unit' + +class TestLambdaParameters < Test::Unit::TestCase + def test_call_simple + assert_equal(1, ->(a){ a }.call(1)) + assert_equal([1,2], ->(a,b){ [a,b] }.call(1,2)) + assert_raises(ArgumentError) { ->(a){ }.call(1,2) } + assert_raises(ArgumentError) { ->(a){ }.call() } + assert_raises(ArgumentError) { ->(){ }.call(1) } + assert_raises(ArgumentError) { ->(a,b){ }.call(1,2,3) } + end + + def test_call_rest_args + assert_equal([1,2], ->(*a){ a }.call(1,2)) + assert_equal([1,2,[]], ->(a,b,*c){ [a,b,c] }.call(1,2)) + assert_raises(ArgumentError){ ->(a,*b){ }.call() } + end + + def test_call_opt_args + assert_equal([1,2,3,4], ->(a,b,c=3,d=4){ [a,b,c,d] }.call(1,2)) + assert_equal([1,2,3,4], ->(a,b,c=0,d=4){ [a,b,c,d] }.call(1,2,3)) + assert_raises(ArgumentError){ ->(a,b=1){ }.call() } + assert_raises(ArgumentError){ ->(a,b=1){ }.call(1,2,3) } + end + + def test_call_rest_and_opt + assert_equal([1,2,3,[]], ->(a,b=2,c=3,*d){ [a,b,c,d] }.call(1)) + assert_equal([1,2,3,[]], ->(a,b=0,c=3,*d){ [a,b,c,d] }.call(1,2)) + assert_equal([1,2,3,[4,5,6]], ->(a,b=0,c=0,*d){ [a,b,c,d] }.call(1,2,3,4,5,6)) + assert_raises(ArgumentError){ ->(a,b=1,*c){ }.call() } + end + + def test_call_with_block + f = ->(a,b,c=3,*d,&e){ [a,b,c,d,e.call(d + [a,b,c])] } + assert_equal([1,2,3,[],6], f.call(1,2){|z| z.inject{|s,x| s+x} } ) + assert_equal(nil, ->(&b){ b }.call) + foo { puts "bogus block " } + assert_equal(1, ->(&b){ b.call }.call { 1 }) + b = nil + assert_equal(1, ->(&b){ b.call }.call { 1 }) + assert_not_nil(b) + end + + def foo + assert_equal(nil, ->(&b){ b }.call) + end + + def test_lambda_as_iterator + a = 0 + 2.times ->(_){ a += 1 } + assert_equal(a, 2) + end +end |