[MacRuby-devel] [PATCH] Support for KVO set accessors

Benjamin Stiglitz ben at tanjero.com
Fri Nov 7 12:30:52 PST 2008


We had arrays, now let's have sets, too. Refactored out the base  
redefinition code to make the set case easy to add.
---
  lib/hotcocoa/kvo_accessors.rb |   39 ++++++++++++++++++++++++++ 
+------------
  1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/lib/hotcocoa/kvo_accessors.rb b/lib/hotcocoa/ 
kvo_accessors.rb
index 1ecacdb..a029413 100644
--- a/lib/hotcocoa/kvo_accessors.rb
+++ b/lib/hotcocoa/kvo_accessors.rb
@@ -2,27 +2,42 @@ class Object

      def self.kvo_array(key, &b)
  	capitalized_key = key.to_s.capitalize
-	signatures = {:size      =>  
{ selector: :"countOf#{capitalized_key}",                   
type_signature: "i@:",   flip: false },
-		      :[]        =>  
{ selector: :"objectIn#{capitalized_key}AtIndex:",          
type_signature: "@@:i",  flip: false },
-		      :insert    =>  
{ selector: :"insertObject:in#{capitalized_key}AtIndex:",   
type_signature: "v@:@i", flip: true  },
-		      :delete_at =>  
{ selector: :"removeObjectFrom#{capitalized_key}AtIndex:",  
type_signature: "v@:i",  flip: false }
+	signatures = { :size      =>  
{ selector: :"countOf#{capitalized_key}",                   
type_signature: "i@:",   flip: false },
+		       :[]        =>  
{ selector: :"objectIn#{capitalized_key}AtIndex:",          
type_signature: "@@:i",  flip: false },
+		       :insert    =>  
{ selector: :"insertObject:in#{capitalized_key}AtIndex:",   
type_signature: "v@:@i", flip: true  },
+		       :delete_at =>  
{ selector: :"removeObjectFrom#{capitalized_key}AtIndex:",  
type_signature: "v@:i",  flip: false }
  	}
+	define_methods_with_signatures(signatures, &b)
+    end
+
+    def self.kvo_set(key, &b)
+	capitalized_key = key.to_s.capitalize
+	signatures = { :add       =>  
{ selector: :"add#{capitalized_key}Object:",    type_signature:  
"v@:@", flip: false },
+		       :delete    =>  
{ selector: :"remove#{capitalized_key}Object:", type_signature:  
"v@:@", flip: false},
+		       :merge     =>  
{ selector: :"add#{capitalized_key}:",          type_signature:  
"v@:@", flip: false },
+		       :subtract  =>  
{ selector: :"remove#{capitalized_key}:",       type_signature:  
"v@:@", flip: false },
+		       :set       =>  
{ selector: :"#{key}",                          type_signature:  
"@@:",  flip: false }
+	}
+	define_methods_with_signatures(signatures, &b)
+    end

+    private
+    def self.define_methods_with_signatures(signatures, &b)
  	c = Module.new
  	c.module_eval &b
  	c.instance_methods.each do |m|
  	    signature = signatures[m]
  	    if signature
-		method = c.instance_method(m)
-		if signature[:flip]
-		    method = Proc.new { |a, b| method.bind(self).call(b, a)}
-		end
-		c.send(:define_method, signature[:selector], method)
-		c.send(:remove_method, m)
-		c.method_signature(signature[:selector], signature[:type_signature])
+	    method = c.instance_method(m)
+	    if signature[:flip]
+		method = Proc.new { |a, b| method.bind(self).call(b, a)}
+	    end
+	    c.send(:define_method, signature[:selector], method)
+	    c.send(:remove_method, m)
+	    c.method_signature(signature[:selector],  
signature[:type_signature])

  	    elsif not Module.instance_methods.include?(m)
-		raise ArgumentError, "Method `#{m}' isn't a KVO array accessor"
+	    raise ArgumentError, "Method `#{m}' isn't a KVO array accessor"
  	    end

  	end
-- 
1.6.0.2



More information about the MacRuby-devel mailing list