Skip to content

Commit 22161c4

Browse files
committed
[GR-18163] Refinements take place at Object#method and Module#instance_method (#2004)
PullRequest: truffleruby/2383
2 parents 5c8578a + 5d1e74f commit 22161c4

File tree

22 files changed

+279
-158
lines changed

22 files changed

+279
-158
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Compatibility:
4747
* Implemented `Module#const_source_location` (#2212, @tomstuart and @wildmaples).
4848
* Do not call `File.exist?` in `Dir.glob` as `File.exist?` is often mocked (#2236, @gogainda).
4949
* Coerce the inherit argument to a boolean in `Module#const_defined?` and `Module#const_get` (#2240).
50+
* Refinements take place at `Object#method` and `Module#instance_method` (#2004, @ssnickolay).
5051

5152
Performance:
5253

lib/truffle/truffle/cext.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ def rb_obj_method_arity(object, id)
423423
object.method(id).arity
424424
end
425425

426+
def rb_obj_method(object, id)
427+
object.method(id)
428+
end
429+
426430
def rb_ivar_defined(object, id)
427431
Primitive.object_ivar_defined?(object, id)
428432
end

spec/ruby/core/kernel/fixtures/classes.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,18 +362,19 @@ class SuperAmpersand
362362
class RespondViaMissing
363363
def respond_to_missing?(method, priv=false)
364364
case method
365-
when :handled_publicly
366-
true
367-
when :handled_privately
368-
priv
369-
when :not_handled
370-
false
371-
else
372-
raise "Typo in method name"
365+
when :handled_publicly
366+
true
367+
when :handled_privately
368+
priv
369+
when :not_handled
370+
false
371+
else
372+
raise "Typo in method name: #{method.inspect}"
373373
end
374374
end
375375

376376
def method_missing(method, *args)
377+
raise "the method name should be a Symbol" unless Symbol === method
377378
"Done #{method}(#{args})"
378379
end
379380
end

spec/ruby/core/kernel/shared/method.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ class KernelSpecs::Foo; def self.bar; 'class done'; end; end
1515
m.call.should == 'class done'
1616
end
1717

18-
it "returns a method object if we repond_to_missing? method" do
18+
it "returns a method object if respond_to_missing?(method) is true" do
1919
m = KernelSpecs::RespondViaMissing.new.send(@method, :handled_publicly)
2020
m.should be_an_instance_of Method
2121
m.call(42).should == "Done handled_publicly([42])"
2222
end
2323

24+
it "the returned method object if respond_to_missing?(method) calls #method_missing with a Symbol name" do
25+
m = KernelSpecs::RespondViaMissing.new.send(@method, "handled_publicly")
26+
m.should be_an_instance_of Method
27+
m.call(42).should == "Done handled_publicly([42])"
28+
end
29+
2430
it "raises a NameError for an invalid method name" do
2531
class KernelSpecs::Foo; def bar; 'done'; end; end
2632
-> {

spec/ruby/core/module/refine_spec.rb

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,43 @@ def foo; end
573573
end
574574
end
575575

576+
ruby_version_is "" ... "2.7" do
577+
it "is not honored by Kernel#public_method" do
578+
klass = Class.new
579+
refinement = Module.new do
580+
refine klass do
581+
def foo; end
582+
end
583+
end
584+
585+
-> {
586+
Module.new do
587+
using refinement
588+
klass.new.public_method(:foo)
589+
end
590+
}.should raise_error(NameError, /undefined method `foo'/)
591+
end
592+
end
593+
594+
ruby_version_is "2.7" do
595+
it "is honored by Kernel#public_method" do
596+
klass = Class.new
597+
refinement = Module.new do
598+
refine klass do
599+
def foo; end
600+
end
601+
end
602+
603+
result = nil
604+
Module.new do
605+
using refinement
606+
result = klass.new.public_method(:foo).class
607+
end
608+
609+
result.should == Method
610+
end
611+
end
612+
576613
ruby_version_is "" ... "2.7" do
577614
it "is not honored by Kernel#instance_method" do
578615
klass = Class.new
@@ -592,7 +629,7 @@ def foo; end
592629
end
593630

594631
ruby_version_is "2.7" do
595-
it "is honored by Kernel#method" do
632+
it "is honored by Kernel#instance_method" do
596633
klass = Class.new
597634
refinement = Module.new do
598635
refine klass do

spec/ruby/optional/capi/ext/kernel_spec.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,6 @@ static VALUE kernel_spec_rb_make_backtrace(VALUE self) {
310310
return rb_make_backtrace();
311311
}
312312

313-
static VALUE kernel_spec_rb_obj_method(VALUE self, VALUE obj, VALUE method) {
314-
return rb_obj_method(obj, method);
315-
}
316-
317313
static VALUE kernel_spec_rb_funcall3(VALUE self, VALUE obj, VALUE method) {
318314
return rb_funcall3(obj, SYM2ID(method), 0, NULL);
319315
}
@@ -366,7 +362,6 @@ void Init_kernel_spec(void) {
366362
rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1);
367363
rb_define_method(cls, "rb_f_sprintf", kernel_spec_rb_f_sprintf, 1);
368364
rb_define_method(cls, "rb_make_backtrace", kernel_spec_rb_make_backtrace, 0);
369-
rb_define_method(cls, "rb_obj_method", kernel_spec_rb_obj_method, 2);
370365
rb_define_method(cls, "rb_funcall3", kernel_spec_rb_funcall3, 2);
371366
rb_define_method(cls, "rb_funcall_many_args", kernel_spec_rb_funcall_many_args, 2);
372367
rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 3);

spec/ruby/optional/capi/ext/object_spec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ static VALUE object_specs_rb_obj_method_arity(VALUE self, VALUE obj, VALUE mid)
147147
return INT2FIX(rb_obj_method_arity(obj, SYM2ID(mid)));
148148
}
149149

150+
static VALUE object_specs_rb_obj_method(VALUE self, VALUE obj, VALUE method) {
151+
return rb_obj_method(obj, method);
152+
}
153+
150154
static VALUE object_spec_rb_obj_taint(VALUE self, VALUE obj) {
151155
return rb_obj_taint(obj);
152156
}
@@ -420,6 +424,7 @@ void Init_object_spec(void) {
420424
rb_define_method(cls, "rb_obj_is_instance_of", so_instance_of, 2);
421425
rb_define_method(cls, "rb_obj_is_kind_of", so_kind_of, 2);
422426
rb_define_method(cls, "rb_obj_method_arity", object_specs_rb_obj_method_arity, 2);
427+
rb_define_method(cls, "rb_obj_method", object_specs_rb_obj_method, 2);
423428
rb_define_method(cls, "rb_obj_taint", object_spec_rb_obj_taint, 1);
424429
rb_define_method(cls, "rb_require", so_require, 0);
425430
rb_define_method(cls, "rb_respond_to", so_respond_to, 2);

spec/ruby/optional/capi/kernel_spec.rb

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -559,20 +559,6 @@ def proc_caller
559559
end
560560
end
561561

562-
describe "rb_obj_method" do
563-
it "returns the method object for a symbol" do
564-
method = @s.rb_obj_method("test", :size)
565-
method.owner.should == String
566-
method.name.to_sym.should == :size
567-
end
568-
569-
it "returns the method object for a string" do
570-
method = @s.rb_obj_method("test", "size")
571-
method.owner.should == String
572-
method.name.to_sym.should == :size
573-
end
574-
end
575-
576562
describe "rb_funcall3" do
577563
before :each do
578564
@obj = Object.new

spec/ruby/optional/capi/object_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@ def six(a, b, *c, &d); end
161161
end
162162
end
163163

164+
describe "rb_obj_method" do
165+
it "returns the method object for a symbol" do
166+
method = @o.rb_obj_method("test", :size)
167+
method.owner.should == String
168+
method.name.to_sym.should == :size
169+
end
170+
171+
it "returns the method object for a string" do
172+
method = @o.rb_obj_method("test", "size")
173+
method.owner.should == String
174+
method.name.to_sym.should == :size
175+
end
176+
end
177+
164178
describe "rb_method_boundp" do
165179
it "returns true when the given method is bound" do
166180
@o.rb_method_boundp(Object, :class, true).should == true

spec/tags/core/module/refine_tags.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
slow:Module#refine method lookup looks in the included modules for builtin methods
2-
fails:Module#refine for methods accessed indirectly is honored by Kernel#method

0 commit comments

Comments
 (0)