[macruby-changes] [3140] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Dec 21 04:34:49 PST 2009
Revision: 3140
http://trac.macosforge.org/projects/ruby/changeset/3140
Author: joshua.ballanco at apple.com
Date: 2009-12-21 04:34:46 -0800 (Mon, 21 Dec 2009)
Log Message:
-----------
Enable aliasing of Objective-C methods
Modified Paths:
--------------
MacRuby/trunk/spec/macruby/core/array_spec.rb
MacRuby/trunk/spec/macruby/core/hash_spec.rb
MacRuby/trunk/spec/macruby/core/string_spec.rb
MacRuby/trunk/spec/macruby/language/objc_method_spec.rb
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/spec/macruby/core/array_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/array_spec.rb 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/spec/macruby/core/array_spec.rb 2009-12-21 12:34:46 UTC (rev 3140)
@@ -79,3 +79,49 @@
end
=end
end
+
+describe "Objective-C Array methods" do
+ before :each do
+ @a = [1,2,3,4]
+ end
+
+ it "should be able to be aliased to other selectors" do
+ class << @a
+ alias :foo :count
+ end
+
+ @a.foo.should == @a.count
+ end
+
+ it "should be able to be aliased by pure Ruby methods" do
+ class << @a
+ def foo
+ return 42
+ end
+ alias :count :foo
+ end
+
+ @a.count.should == 42
+ end
+
+ it "should be commutative when aliased" do
+ class << @a
+ def foo
+ return 42
+ end
+ def do_alias
+ alias :old_count :count
+ alias :count :foo
+ end
+ def undo_alias
+ alias :count :old_count
+ end
+ end
+
+ @a.count.should == 4
+ @a.do_alias
+ @a.count.should == 42
+ @a.undo_alias
+ @a.count.should == 4
+ end
+end
Modified: MacRuby/trunk/spec/macruby/core/hash_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/hash_spec.rb 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/spec/macruby/core/hash_spec.rb 2009-12-21 12:34:46 UTC (rev 3140)
@@ -77,3 +77,49 @@
lambda { a[42] = 123 }.should raise_error(RuntimeError)
end
end
+
+describe "Objective-C Hash methods" do
+ before :each do
+ @a = {:a => 1, :b => 2, :c => 3}
+ end
+
+ it "should be able to be aliased to other selectors" do
+ class << @a
+ alias :foo :count
+ end
+
+ @a.foo.should == @a.count
+ end
+
+ it "should be able to be aliased by pure Ruby methods" do
+ class << @a
+ def foo
+ return 42
+ end
+ alias :count :foo
+ end
+
+ @a.count.should == 42
+ end
+
+ it "should be commutative when aliased" do
+ class << @a
+ def foo
+ return 42
+ end
+ def do_alias
+ alias :old_count :count
+ alias :count :foo
+ end
+ def undo_alias
+ alias :count :old_count
+ end
+ end
+
+ @a.count.should == 4
+ @a.do_alias
+ @a.count.should == 42
+ @a.undo_alias
+ @a.count.should == 4
+ end
+end
Modified: MacRuby/trunk/spec/macruby/core/string_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/core/string_spec.rb 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/spec/macruby/core/string_spec.rb 2009-12-21 12:34:46 UTC (rev 3140)
@@ -81,3 +81,49 @@
#lambda { a << 'foo' }.should raise_error(RuntimeError)
end
end
+
+describe "Objective-C String methods" do
+ before :each do
+ @a = "test"
+ end
+
+ it "should be able to be aliased to other selectors" do
+ class << @a
+ alias :foo :length
+ end
+
+ @a.foo.should == @a.length
+ end
+
+ it "should be able to be aliased by pure Ruby methods" do
+ class << @a
+ def foo
+ return 42
+ end
+ alias :length :foo
+ end
+
+ @a.length.should == 42
+ end
+
+ it "should be commutative when aliased" do
+ class << @a
+ def foo
+ return 42
+ end
+ def do_alias
+ alias :old_length :length
+ alias :length :foo
+ end
+ def undo_alias
+ alias :length :old_length
+ end
+ end
+
+ @a.length.should == 4
+ @a.do_alias
+ @a.length.should == 42
+ @a.undo_alias
+ @a.length.should == 4
+ end
+end
Modified: MacRuby/trunk/spec/macruby/language/objc_method_spec.rb
===================================================================
--- MacRuby/trunk/spec/macruby/language/objc_method_spec.rb 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/spec/macruby/language/objc_method_spec.rb 2009-12-21 12:34:46 UTC (rev 3140)
@@ -408,6 +408,49 @@
end
@o.methodAcceptingSEL('foo:arg1:arg2:', target:o)
end
+
+ it "can have another method aliased to it" do
+ class << @o
+ alias :test_method :methodReturningSelf
+ end
+
+ @o.should.respond_to(:test_method)
+ @o.test_method.should == @o
+ @o.test_method.object_id.should == @o.object_id
+ end
+
+ it "can be aliased to a pure Ruby method" do
+ class << @o
+ def foo
+ return 42
+ end
+ alias :methodReturningSelf :foo
+ end
+
+ @o.should.respond_to(:methodReturningSelf)
+ @o.methodReturningSelf.should == 42
+ end
+
+ it "should be commutative when aliased" do
+ class << @o
+ def foo
+ return 42
+ end
+ def do_alias
+ alias :old_methodReturningSelf :methodReturningSelf
+ alias :methodReturningSelf :foo
+ end
+ def undo_alias
+ alias :methodReturningSelf :old_methodReturningSelf
+ end
+ end
+
+ @o.methodReturningSelf.should == @o
+ @o.do_alias
+ @o.methodReturningSelf.should == 42
+ @o.undo_alias
+ @o.methodReturningSelf.should == @o
+ end
end
describe "A pure MacRuby method" do
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/vm.cpp 2009-12-21 12:34:46 UTC (rev 3140)
@@ -1464,11 +1464,6 @@
const char *types = method_getTypeEncoding(method);
rb_vm_method_node_t *node = GET_CORE()->method_node_get(method);
- if (node == NULL) {
- rb_raise(rb_eArgError,
- "only pure Ruby methods can be aliased (`%s' is not)",
- sel_getName(method_getName(method)));
- }
const char *name_str = rb_id2name(name);
SEL sel;
@@ -1481,8 +1476,27 @@
sel = sel_registerName(tmp);
}
- GET_CORE()->add_method(klass, sel, imp, node->ruby_imp,
- node->arity, node->flags, types);
+ if (node == NULL) {
+ Method method_to_replace = class_getInstanceMethod(klass, sel);
+ rb_vm_method_node_t *node_to_replace = GET_CORE()->method_node_get(method_to_replace);
+ if ((klass == (Class)rb_cCFString || klass == (Class)rb_cCFHash)
+ && node_to_replace != NULL) {
+ //Doesn't work:
+ //GET_CORE()->remove_method(klass, sel);
+ //
+ //This, apparently, doesn't work either...
+ //GET_CORE()->add_method(klass, sel, imp, imp,
+ // arity, 0, types);
+ //
+ //This...sorta...works...
+ GET_CORE()->nuke_method(method_to_replace);
+ }
+ class_replaceMethod(klass, sel, imp, types);
+ }
+ else {
+ GET_CORE()->add_method(klass, sel, imp, node->ruby_imp,
+ node->arity, node->flags, types);
+ }
}
extern "C"
@@ -1503,6 +1517,15 @@
const char *def_str = rb_id2name(def);
SEL sel = sel_registerName(def_str);
+
+ // String and Hash aliases should be defined on the Core Foundation classes
+ if (klass == (Class)rb_cNSMutableString) {
+ klass = (Class)rb_cCFString;
+ }
+ if (klass == (Class)rb_cNSMutableHash) {
+ klass = (Class)rb_cCFHash;
+ }
+
Method def_method1 = class_getInstanceMethod(klass, sel);
Method def_method2 = NULL;
if (def_str[strlen(def_str) - 1] != ':') {
@@ -2535,6 +2558,16 @@
}
}
+void
+RoxorCore::nuke_method(Method m)
+{
+ invalidate_method_cache(method_getName(m));
+ std::map<Method, rb_vm_method_node_t *>::iterator iter = ruby_methods.find(m);
+ assert(iter != ruby_methods.end());
+ free(iter->second);
+ ruby_methods.erase(iter);
+}
+
extern "C"
void
rb_vm_undef_method(Class klass, ID name, bool must_exist)
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2009-12-19 01:50:51 UTC (rev 3139)
+++ MacRuby/trunk/vm.h 2009-12-21 12:34:46 UTC (rev 3140)
@@ -757,6 +757,7 @@
rb_vm_method_node_t *node, const char *types);
void undef_method(Class klass, SEL sel);
void remove_method(Class klass, SEL sel);
+ void nuke_method(Method m);
bool resolve_methods(std::map<Class, rb_vm_method_source_t *> *map,
Class klass, SEL sel);
bool copy_method(Class klass, Method m);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091221/005adcbe/attachment.html>
More information about the macruby-changes
mailing list