Revision: 3919 http://trac.macosforge.org/projects/ruby/changeset/3919 Author: eloy.de.enige@gmail.com Date: 2010-04-12 14:34:42 -0700 (Mon, 12 Apr 2010) Log Message: ----------- Always try helper methods if a class is not a RubyObject descendant. This means that helper methods, such as #foo= => #setFoo will still work, even if the objc method is overriden from Ruby. Modified Paths: -------------- MacRuby/trunk/dispatcher.cpp MacRuby/trunk/spec/macruby/language/objc_method_spec.rb Modified: MacRuby/trunk/dispatcher.cpp =================================================================== --- MacRuby/trunk/dispatcher.cpp 2010-04-11 01:57:40 UTC (rev 3918) +++ MacRuby/trunk/dispatcher.cpp 2010-04-12 21:34:42 UTC (rev 3919) @@ -677,24 +677,26 @@ } } - // Let's try to see if we are not given a helper selector. - SEL new_sel = helper_sel(selname, selname_len); - if (new_sel != NULL) { - Method m = class_getInstanceMethod(klass, new_sel); - if (m != NULL) { - if (GET_CORE()->method_node_get(m) == NULL) { - sel = new_sel; - method = m; - // We need to invert arguments because - // #[]= and setObject:forKey: take arguments - // in a reverse order - if (new_sel == selSetObjectForKey && argc == 2) { - VALUE swap = argv[0]; - ((VALUE *)argv)[0] = argv[1]; - ((VALUE *)argv)[1] = swap; - cache_method = false; - } - goto recache2; + // Enable helpers for classes which are not RubyObject based. + if ((RCLASS_VERSION(klass) & RCLASS_IS_OBJECT_SUBCLASS) + != RCLASS_IS_OBJECT_SUBCLASS) { + // Let's try to see if we are not given a helper selector. + SEL new_sel = helper_sel(selname, selname_len); + if (new_sel != NULL) { + Method m = class_getInstanceMethod(klass, new_sel); + if (m != NULL) { + sel = new_sel; + method = m; + // We need to invert arguments because + // #[]= and setObject:forKey: take arguments + // in a reverse order + if (new_sel == selSetObjectForKey && argc == 2) { + VALUE swap = argv[0]; + ((VALUE *)argv)[0] = argv[1]; + ((VALUE *)argv)[1] = swap; + cache_method = false; + } + goto recache2; } } } Modified: MacRuby/trunk/spec/macruby/language/objc_method_spec.rb =================================================================== --- MacRuby/trunk/spec/macruby/language/objc_method_spec.rb 2010-04-11 01:57:40 UTC (rev 3918) +++ MacRuby/trunk/spec/macruby/language/objc_method_spec.rb 2010-04-12 21:34:42 UTC (rev 3919) @@ -3,26 +3,44 @@ require File.join(FIXTURES, 'method') +class SubclassedTestMethod < TestMethod + def setFoo(x) + super(x * 2) + end + + def isFoo + !super + end +end + describe "A pure Objective-C method" do before :each do @o = TestMethod.new end - it "can be called with #foo= if it matches the #setFoo pattern" do - @o.should respond_to(:'setFoo') - @o.should respond_to(:'foo=') + it "can be called with #foo= if it matches the #setFoo pattern, also when overridden from Ruby" do + o2 = SubclassedTestMethod.new + [ + [@o, 123, 123, 456, 456], + [o2, 123, 246, 456, 912] + ].each do |o, v1, rv1, v2, rv2| + o.should respond_to(:'setFoo') + o.should respond_to(:'foo=') - @o.setFoo(123) - @o.foo.should == 123 - @o.foo = 456 - @o.foo.should == 456 + o.setFoo(v1) + o.foo.should == rv1 + o.foo = v2 + o.foo.should == rv2 + end end - it "can be called with #foo? if it matches the #isFoo pattern" do - @o.should respond_to(:'isFoo') - @o.should respond_to(:'foo?') - - @o.foo?.should equal(@o.isFoo) + it "can be called with #foo? if it matches the #isFoo pattern, also when overridden from Ruby" do + o2 = SubclassedTestMethod.new + [@o, o2].each do |o| + o.should respond_to(:'isFoo') + o.should respond_to(:'foo?') + o.foo?.should equal(o.isFoo) + end end it "is only exposed in #methods if the second argument is true" do