ruby-changes:47861
From: eregon <ko1@a...>
Date: Thu, 21 Sep 2017 07:02:25 +0900 (JST)
Subject: [ruby-changes:47861] eregon:r59982 (trunk): check_funcall_missing() should call respond_to_missing?(name, priv=true)
eregon 2017-09-21 07:02:10 +0900 (Thu, 21 Sep 2017) New Revision: 59982 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59982 Log: check_funcall_missing() should call respond_to_missing?(name, priv=true) * Improve spec rather than constrain implementation. * Coercion ignores visibility in Ruby. Modified files: trunk/spec/ruby/core/array/flatten_spec.rb trunk/vm_eval.c Index: spec/ruby/core/array/flatten_spec.rb =================================================================== --- spec/ruby/core/array/flatten_spec.rb (revision 59981) +++ spec/ruby/core/array/flatten_spec.rb (revision 59982) @@ -111,18 +111,34 @@ describe "Array#flatten" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/flatten_spec.rb#L111 lambda { [@obj].flatten }.should raise_error(TypeError) end + ruby_version_is ""..."2.5" do + it "calls respond_to_missing?(:to_ary, false) to try coercing" do + def @obj.respond_to_missing?(*args) ScratchPad << args; false end + [@obj].flatten.should == [@obj] + ScratchPad.recorded.should == [[:to_ary, false]] + end + end + + ruby_version_is "2.5" do + it "calls respond_to_missing?(:to_ary, true) to try coercing" do + def @obj.respond_to_missing?(*args) ScratchPad << args; false end + [@obj].flatten.should == [@obj] + ScratchPad.recorded.should == [[:to_ary, true]] + end + end + it "does not call #to_ary if not defined when #respond_to_missing? returns false" do - def @obj.respond_to_missing?(*args) ScratchPad << args; false end + def @obj.respond_to_missing?(name, priv) ScratchPad << name; false end [@obj].flatten.should == [@obj] - ScratchPad.recorded.should == [[:to_ary, false]] + ScratchPad.recorded.should == [:to_ary] end it "calls #to_ary if not defined when #respond_to_missing? returns true" do - def @obj.respond_to_missing?(*args) ScratchPad << args; true end + def @obj.respond_to_missing?(name, priv) ScratchPad << name; true end lambda { [@obj].flatten }.should raise_error(NoMethodError) - ScratchPad.recorded.should == [[:to_ary, false]] + ScratchPad.recorded.should == [:to_ary] end it "calls #method_missing if defined" do Index: vm_eval.c =================================================================== --- vm_eval.c (revision 59981) +++ vm_eval.c (revision 59982) @@ -315,8 +315,6 @@ check_funcall_exec(struct rescue_funcall https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L315 args->me, args->argc, args->argv); } -#define PRIV Qfalse /* TODO: for rubyspec now, should be Qtrue */ - static VALUE check_funcall_failed(struct rescue_funcall_args *args, VALUE e) { @@ -361,7 +359,7 @@ check_funcall_missing(rb_thread_t *th, V https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L359 VALUE ret = Qundef; ret = basic_obj_respond_to_missing(th, klass, recv, - ID2SYM(mid), PRIV); + ID2SYM(mid), Qtrue); if (!RTEST(ret)) return def; args.respond = respond > 0; args.respond_to_missing = (ret != Qundef); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/