summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-29 17:47:24 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-10-29 17:47:24 +0000
commit525336fcc97a0c0fc8dae2e6f9fe63dfc6e645ab (patch)
tree23b84c6d3aa98723fea6577ecedbb3d15a49baba
parent2e0b6e28ada7713aab10343c2850f32dec4652ac (diff)
* eval.c (proc_invoke): single array value to normal Proc#call
(i.e. not via lambda call), should be treated just like yield. [ruby-dev:21726] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--eval.c8
-rw-r--r--lib/cgi.rb6
-rw-r--r--lib/optparse.rb1
-rw-r--r--parse.y17
-rw-r--r--sample/test.rb14
-rw-r--r--test/ruby/test_assignment.rb14
-rw-r--r--test/ruby/test_iterator.rb26
8 files changed, 71 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 963ea9129c..3118694014 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu Oct 30 02:46:35 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (proc_invoke): single array value to normal Proc#call
+ (i.e. not via lambda call), should be treated just like yield.
+ [ruby-dev:21726]
+
Thu Oct 30 02:25:48 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* ext/openssl/lib/openssl/buffering.rb (Buffering#initialize):
@@ -57,12 +63,6 @@ Tue Oct 28 15:20:12 2003 NAKAMURA Usaku <usa@ruby-lang.org>
ip_rb_threadVwaitObjCmd, ip_rb_threadTkWaitObjCmd): prototype;
avoid VC++ warnings.
-Tue Oct 28 11:24:18 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
-
- * parse.y (new_yield): remove magic argument rule; "yield [1,2]"
- should yield single array of two elements, not two values.
- [ruby-dev:21726]
-
Mon Oct 27 19:19:55 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_longjmp): ignore reentering error while warning.
diff --git a/eval.c b/eval.c
index 1078b85fcb..d5e356991c 100644
--- a/eval.c
+++ b/eval.c
@@ -7053,7 +7053,7 @@ proc_invoke(proc, args, self, klass)
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
struct RVarmap * volatile old_dvars = ruby_dyna_vars;
- volatile int pcall;
+ volatile int pcall, avalue = Qtrue;
if (rb_block_given_p() && ruby_frame->last_func) {
rb_warning("block for %s#%s is useless",
@@ -7064,6 +7064,10 @@ proc_invoke(proc, args, self, klass)
Data_Get_Struct(proc, struct BLOCK, data);
orphan = block_orphan(data);
pcall = data->flags & BLOCK_LAMBDA ? YIELD_PROC_CALL : 0;
+ if (!pcall && RARRAY(args)->len == 1) {
+ avalue = Qfalse;
+ args = RARRAY(args)->ptr[0];
+ }
ruby_wrapper = data->wrapper;
ruby_dyna_vars = data->dyna_vars;
@@ -7080,7 +7084,7 @@ proc_invoke(proc, args, self, klass)
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(proc);
- result = rb_yield_0(args, self, self!=Qundef?CLASS_OF(self):0, pcall, Qtrue);
+ result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall, avalue);
}
else if (pcall || orphan || TAG_DST()) {
result = prot_tag->retval;
diff --git a/lib/cgi.rb b/lib/cgi.rb
index a6003d99a6..43a5aa89f0 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -1152,11 +1152,9 @@ class CGI
end
alias last first
def to_a
- @params
- end
- def to_ary # to be rhs of multiple assignment
- @params
+ @params || [self]
end
+ alias to_ary to_a # to be rhs of multiple assignment
end
# Get the value for the parameter with a given key.
diff --git a/lib/optparse.rb b/lib/optparse.rb
index 38958c3f8d..22c03ff5ee 100644
--- a/lib/optparse.rb
+++ b/lib/optparse.rb
@@ -168,6 +168,7 @@ Individual switch class.
def initialize(pattern = nil, conv = nil,
short = nil, long = nil, arg = nil,
desc = ([] if short or long), block = Proc.new)
+ raise if Array === pattern
@pattern, @conv, @short, @long, @arg, @desc, @block =
pattern, conv, short, long, arg, desc, block
end
diff --git a/parse.y b/parse.y
index 75fa33e820..5c43cd81da 100644
--- a/parse.y
+++ b/parse.y
@@ -5377,7 +5377,22 @@ static NODE *
new_yield(node)
NODE *node;
{
- return NEW_YIELD(node, node ? Qtrue : Qfalse);
+ long state = Qtrue;
+
+ if (node) {
+ no_blockarg(node);
+ if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
+ node = node->nd_head;
+ state = Qfalse;
+ }
+ if (node && nd_type(node) == NODE_SPLAT) {
+ state = Qtrue;
+ }
+ }
+ else {
+ state = Qfalse;
+ }
+ return NEW_YIELD(node, state);
}
static NODE*
diff --git a/sample/test.rb b/sample/test.rb
index 02befbedc1..6488558fd1 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -151,13 +151,13 @@ def f; yield *[*[1,2]]; end; f {|*a| test_ok(a == [1,2])}
def f; yield; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield 1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
-def f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
-def f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [[1],nil,[]])}
-def f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [[nil],nil,[]])}
-def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[[]],nil,[]])}
-def f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
-def f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [[1],nil,[]])}
-def f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [[1,2],nil,[]])}
+def f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
+def f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
+def f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
+def f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
def f; yield *nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield *1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
diff --git a/test/ruby/test_assignment.rb b/test/ruby/test_assignment.rb
index e78021558f..51d1c780f8 100644
--- a/test/ruby/test_assignment.rb
+++ b/test/ruby/test_assignment.rb
@@ -130,13 +130,13 @@ class TestAssignment < Test::Unit::TestCase
def f; yield; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
def f; yield nil; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
def f; yield 1; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}
- def f; yield []; end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}
- def f; yield [1]; end; f {|a,b,*c| assert_equal([[1],nil,[]], [a,b,c])}
- def f; yield [nil]; end; f {|a,b,*c| assert_equal([[nil],nil,[]], [a,b,c])}
- def f; yield [[]]; end; f {|a,b,*c| assert_equal([[[]],nil,[]], [a,b,c])}
- def f; yield [*[]]; end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}
- def f; yield [*[1]]; end; f {|a,b,*c| assert_equal([[1],nil,[]], [a,b,c])}
- def f; yield [*[1,2]]; end; f {|a,b,*c| assert_equal([[1,2],nil,[]], [a,b,c])}
+ def f; yield []; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
+ def f; yield [1]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}
+ def f; yield [nil]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
+ def f; yield [[]]; end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}
+ def f; yield [*[]]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
+ def f; yield [*[1]]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}
+ def f; yield [*[1,2]]; end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}
def f; yield *nil; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}
def f; yield *1; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}
diff --git a/test/ruby/test_iterator.rb b/test/ruby/test_iterator.rb
index 60bfad50a9..c8631653f3 100644
--- a/test/ruby/test_iterator.rb
+++ b/test/ruby/test_iterator.rb
@@ -328,6 +328,32 @@ class TestIterator < Test::Unit::TestCase
lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity")
end
+ def foo
+ yield([:key, :value])
+ end
+ def bar(&blk)
+ blk.call([:key, :value])
+ end
+
+ def test_yield_vs_call
+ foo{|k,v| assert_equal([:key, :value], [k,v])}
+ bar{|k,v| assert_equal([:key, :value], [k,v])}
+ end
+
+ class H
+ def each
+ yield [:key, :value]
+ end
+ end
+
+ def test_assoc_yield
+ [{:key=>:value}, H.new].each {|h|
+ h.each{|a| assert_equal([:key, :value], a)}
+ h.each{|*a| assert_equal([[:key, :value]], a)}
+ h.each{|k,v| assert_equal([:key, :value], [k,v])}
+ }
+ end
+
class ITER_TEST1
def a
block_given?