Permalink
Browse files

Initial release, v0.1.0

  • Loading branch information...
1 parent a010102 commit 0c4d89918fd0174f688710375f2410d6cf387c1b @PlasticLizard committed Oct 6, 2010
Showing with 115 additions and 19 deletions.
  1. +1 −1 LICENSE
  2. +113 −13 README.rdoc
  3. +1 −1 lib/observables/version.rb
  4. +0 −2 observables.gemspec
  5. +0 −2 test/test_helper.rb
View
@@ -1,4 +1,4 @@
-Copyright (c) 2009 Nathan Stults
+Copyright (c) 2010 Nathan Stults
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
View
@@ -1,17 +1,117 @@
-= Observables
+ = Observables
-Description goes here.
+ Observables implements observable arrays and hashes by way of the ActiveModel::Notifier, the same mechanism
+ underlying the instrumentation API in Rails3. Observables collections broadcast detailed change information for
+ any state-modifying operations, including specific elements added or removed, when that information is practically
+ obtainable.
-== Note on Patches/Pull Requests
-
-* Fork the project.
-* Make your feature addition or bug fix.
-* Add tests for it. This is important so I don't break it in a
- future version unintentionally.
-* Commit, do not mess with rakefile, version, or history.
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-* Send me a pull request. Bonus points for topic branches.
+ == Installation
-== Copyright
+ Observables is available as a RubyGem:
-Copyright (c) 2010 Nathan Stults. See LICENSE for details.
+ gem install observables
+
+ == Observing the Observables
+
+ === Example:
+
+ #Getting an observable array
+
+ ary = [1,2,3] #or, ary = Observables::Array.new([1,2,3]), or, hsh = Observables::Hash
+ ary.observable? # => false
+ ary.can_be_observable? # => true
+ ary.make_observable => #<Class:#<Array:0x56a84a8>>
+
+ #Setting up a subscription
+
+ subscription = ary.subscribe do |change_type,args|
+ puts "Change type: #{change_type}"
+ puts "Trigger: #{args.trigger}"
+ puts "Changes: #{args.changes.inspect}"
+ puts "---"
+ end
+
+ #Do stuff
+
+ ary << 3
+ # Change type: before_added
+ # Trigger: <<
+ # Changes: {:added=>[3]}
+ # ---
+ # Change type: after_added
+ # Trigger: <<
+ # Changes: {:added=>[3]}
+ # => [1,2,3,3]
+
+ #Clean up
+
+ ary.unsubscribe(subscription)
+ ary << 4 # => [1,2,3,3,4]
+
+ #Only listen to after_xxx
+
+ subscription = ary.subscribe(/after/) do |change_type,_|
+ puts "Change type:#{change_type}"
+ end
+
+ ary.concat([9,10,11])
+
+ # Change type: after_added, changes: {:added=>[9,10,11]}
+ # => [1,2,3,3,4,9,10,11]
+
+ ary.replace([3,2,1])
+
+ # Change type: after_modified, changed: {:added=>[3,2,1], :removed=>[1,2,3,3,4,9,10,11]}
+ # => [3,2,1]
+
+ #Hashes work too
+
+ hsh = {:a=>:b}
+ hsh.can_be_observable? # => true
+ hsh.make_observable
+ hsh.subscribe { |type,args| ... }
+
+ == Special case: ownership
+
+ Observables was created to assist in the implementation of proper dirty tracking for in-place modifications
+ to embedded collections in ORM's, particularly for documented oriented databases, where
+ this is a common situation. In this scenario and similar scenarios, observable collections
+ will only be subscribed to by the object that owns them. However, the parent object
+ may own any number of child collections. To avoid having to manage myriad subscription
+ objects, each observable collection can have a single 'observer' - and will manage the
+ subscription to that observer like so:
+
+ class Owner
+ def my_array
+ @my_array
+ end
+
+ def my_array=(new_array)
+ @my_array.clear_observer if @my_array
+ @my_array = new_array.tap {|a|a.make_observable}
+ @my_array.set_observer(self, :pattern=>/before/, :callback_method=>:my_array_before_change)
+ #Acceptable alernatives are:
+ # @my_array.set_observer { |type,args| ... }
+ # @my_array.set_observer(self, :pattern=>/before/) { |sender,type,args| ... }
+ end
+
+ def my_array_before_change(sender,type,args)
+ #sender = @my_array
+ #do something interesting, like, say, attribute_will_change!(:my_array)
+ end
+
+ end
+
+ == Note on Patches/Pull Requests
+
+ * Fork the project.
+ * Make your feature addition or bug fix.
+ * Add tests for it. This is important so I don't break it in a
+ future version unintentionally.
+ * Commit, do not mess with rakefile, version, or history.
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
+ * Send me a pull request. Bonus points for topic branches.
+
+ == Copyright
+
+ Copyright (c) 2010 Nathan Stults. See LICENSE for details.
@@ -1,4 +1,4 @@
# encoding: UTF-8
module Observables
- Version = '0.0.1'
+ Version = '0.1.0'
end
View
@@ -19,7 +19,5 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rake'
s.add_development_dependency 'shoulda', '~> 2.11'
- s.add_development_dependency 'timecop', '~> 0.3.1'
- s.add_development_dependency 'mocha', '~> 0.9.8'
end
View
@@ -6,8 +6,6 @@
require 'observables'
require 'shoulda'
-require 'timecop'
-require 'mocha'
class Test::Unit::TestCase

0 comments on commit 0c4d899

Please sign in to comment.