[MacRuby-devel] [PATCH] Added KVO array accessors

Benjamin Stiglitz ben at tanjero.com
Fri Nov 7 10:43:25 PST 2008


These changes let you write methods for KVO accessing using natural  
Ruby syntax:

class T
kvo_array :squares do
   def size
     10
   end
   def [](i)
     i * i
   end
end
end

 >> T.new.valueForKey('squares')
=> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

---
lib/hotcocoa.rb               |    1 +
lib/hotcocoa/kvo_accessors.rb |   33 +++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
create mode 100644 lib/hotcocoa/kvo_accessors.rb

diff --git a/lib/hotcocoa.rb b/lib/hotcocoa.rb
index 4ca61f0..8b294e9 100644
--- a/lib/hotcocoa.rb
+++ b/lib/hotcocoa.rb
@@ -17,5 +17,6 @@ require 'hotcocoa/data_sources/table_data_source'
require 'hotcocoa/data_sources/combo_box_data_source'
require 'hotcocoa/kernel_ext'
require 'hotcocoa/plist'
+require 'hotcocoa/kvo_accessors'

HotCocoa::Mappings.reload
diff --git a/lib/hotcocoa/kvo_accessors.rb b/lib/hotcocoa/ 
kvo_accessors.rb
new file mode 100644
index 0000000..1ecacdb
--- /dev/null
+++ b/lib/hotcocoa/kvo_accessors.rb
@@ -0,0 +1,33 @@
+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 }
+	}
+
+	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])
+
+	    elsif not Module.instance_methods.include?(m)
+		raise ArgumentError, "Method `#{m}' isn't a KVO array accessor"
+	    end
+
+	end
+
+	include c
+    end
+
+end
-- 
1.6.0.2



More information about the MacRuby-devel mailing list