[macruby-changes] [3244] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Jan 11 14:57:51 PST 2010


Revision: 3244
          http://trac.macosforge.org/projects/ruby/changeset/3244
Author:   martinlagardette at apple.com
Date:     2010-01-11 14:57:50 -0800 (Mon, 11 Jan 2010)
Log Message:
-----------
 - Fixes #531 by implementing #[] and #[]= as shortcuts for objectForKey: and setObject:forKey:

Modified Paths:
--------------
    MacRuby/trunk/dispatcher.cpp
    MacRuby/trunk/id.c
    MacRuby/trunk/id.h
    MacRuby/trunk/spec/macruby/fixtures/method.m
    MacRuby/trunk/spec/macruby/fixtures/method.rb

Modified: MacRuby/trunk/dispatcher.cpp
===================================================================
--- MacRuby/trunk/dispatcher.cpp	2010-01-11 21:47:24 UTC (rev 3243)
+++ MacRuby/trunk/dispatcher.cpp	2010-01-11 22:57:50 UTC (rev 3244)
@@ -202,6 +202,12 @@
 	buf[len + 1] = '\0';
 	new_sel = sel_registerName(buf);
     }
+    else if (strcmp(p, "[]:") == 0) {
+	new_sel = selObjectForKey;
+    }
+    else if (strcmp(p, "[]=:") == 0) {
+	new_sel = selSetObjectForKey;
+    }
 
     return new_sel;
 }
@@ -566,7 +572,7 @@
 #if ROXOR_VM_DEBUG
     bool cached = true;
 #endif
-    bool do_rcache = true;
+    bool cache_method = true;
 
     if (cache->flag == 0) {
 recache:
@@ -650,7 +656,7 @@
 			Method m = class_getInstanceMethod(klass, sel);
 			if (m != NULL) {	
 			    method = m;
-			    do_rcache = false;
+			    cache_method = false;
 			    goto recache2;
 			}
 		    }
@@ -665,6 +671,15 @@
 		    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;
 		    }
 		}
@@ -699,7 +714,7 @@
 	if (rcache.klass != klass) {
 	    goto recache;
 	}
-	if (!do_rcache) {
+	if (!cache_method) {
 	    cache->flag = 0;
 	}
 
@@ -773,6 +788,9 @@
 	if (ocache.klass != klass) {
 	    goto recache;
 	}
+	if (!cache_method) {
+	    cache->flag = 0;
+	}
 
 	if (block != NULL) {
 	    if (self == rb_cNSMutableHash && sel == selNew) {

Modified: MacRuby/trunk/id.c
===================================================================
--- MacRuby/trunk/id.c	2010-01-11 21:47:24 UTC (rev 3243)
+++ MacRuby/trunk/id.c	2010-01-11 22:57:50 UTC (rev 3244)
@@ -105,6 +105,8 @@
     selWrite = sel_registerName("write:");
     selInherited = sel_registerName("inherited:");
     selLambda = sel_registerName("lambda");
+    selObjectForKey = sel_registerName("objectForKey:");
+    selSetObjectForKey = sel_registerName("setObject:forKey:");
 
     cacheEach = rb_vm_get_call_cache(selEach);
 #endif

Modified: MacRuby/trunk/id.h
===================================================================
--- MacRuby/trunk/id.h	2010-01-11 21:47:24 UTC (rev 3243)
+++ MacRuby/trunk/id.h	2010-01-11 22:57:50 UTC (rev 3244)
@@ -114,6 +114,8 @@
 extern SEL selWrite;
 extern SEL selInherited;
 extern SEL selLambda;
+extern SEL selObjectForKey;
+extern SEL selSetObjectForKey;
 extern ID idIncludedModules;
 extern ID idIncludedInClasses;
 extern ID idAncestors;

Modified: MacRuby/trunk/spec/macruby/fixtures/method.m
===================================================================
--- MacRuby/trunk/spec/macruby/fixtures/method.m	2010-01-11 21:47:24 UTC (rev 3243)
+++ MacRuby/trunk/spec/macruby/fixtures/method.m	2010-01-11 22:57:50 UTC (rev 3244)
@@ -10,11 +10,27 @@
 @interface TestMethod : NSObject
 {
     id _foo;
+    NSMutableDictionary *dic;
 }
 @end
 
 @implementation TestMethod
 
+- (id)init
+{
+    if (self = [super init])
+    {
+        dic = [[NSMutableDictionary alloc] init];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [dic release];
+    [super dealloc];
+}
+
 - (BOOL)isFoo
 {
     return YES;
@@ -35,6 +51,16 @@
     return _foo;
 }
 
+- (void)setObject:(id)obj forKey:(NSString *)key
+{
+    [dic setObject:obj forKey:key];
+}
+
+- (id)objectForKey:(NSString *)key
+{
+    return [dic objectForKey:key];
+}
+
 - (void)methodReturningVoid
 {
 }

Modified: MacRuby/trunk/spec/macruby/fixtures/method.rb
===================================================================
--- MacRuby/trunk/spec/macruby/fixtures/method.rb	2010-01-11 21:47:24 UTC (rev 3243)
+++ MacRuby/trunk/spec/macruby/fixtures/method.rb	2010-01-11 22:57:50 UTC (rev 3244)
@@ -69,3 +69,16 @@
     x + x2 == 42
   end
 end
+
+require File.dirname(__FILE__) + "/../spec_helper"
+
+describe "An Obj-C object" do
+  before :each do
+    @o = TestMethod.new
+  end
+
+  it "allows the use of #[] and #[]= as respective shortcuts to objectForKey: and setObject:forKey:" do
+    @o['foo'] = 'ok'
+    @o['foo'].should == 'ok'
+  end
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100111/39ea88a5/attachment.html>


More information about the macruby-changes mailing list