<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -15,37 +15,65 @@ DataMapper observer capabilities are automatically available when you
     include DataMapper::Resource
     include DataMapper::Observers::Observable
     property :id, Integer, :key =&gt; true
+    
+    def my_instance_method
+      puts &quot;my_instance_method called&quot;
+    end
   end
 
   class MyObserver &lt; DataMapper::Observers::Observer
-    def before_save(object)
-      puts &quot;Before save...&quot;
-      # ...
+    
+    before :save do
+      puts &quot;before :save block...&quot;
     end
-  
-    def after_save(object)
-      puts &quot;After save...&quot;
+    
+    after :destroy do
+      puts &quot;after :destroy block...&quot;
+    end
+    
+    before :my_instance_method do
+      puts &quot;before :my_instance_method block...&quot;
       # ...
     end
-  
+    
+    before :my_instance_method do |object|
+      puts &quot;before :my_instance_method block with object parameter #{object.inspect}...&quot;
+      #...
+    end
+    
     # ...
   end
 
-  MyModel.add_observer(MyObserver.instance)
+  MyObserver.instance.observed_class = MyModel
 
-  MyModel.new.save
+  MyModel.auto_migrate!
+  object = MyModel.new
+  
+  object.my_instance_method
+  ---- output ----
+  before :my_instance_method block...
+  before :my_instance_method block with object parameter #&lt;MyModel id=nil&gt;...
+  my_instance_method called
+  ---- output ----
+  
+  object.save
+  ---- output ----
+  before :save block...
+  ---- output ----
 
----- output ----
-Before save...
-After save...
----- output ----
+  object.destroy
+  ---- output ----
+  after :destroy block...
+  ---- output ----
 
 
-The following are the hooks that are automatically called on the observers
-before or after each model CRUD operation, if they are defined:
+The methods &quot;before&quot; and &quot;after&quot; take a target method parameter -- the name of the method at
+the model to observe -- and a block -- the code to execute before/after the target method is
+executed. The syntax is pretty similar to model hooks, just that it doesn't support class methods
+or method symbols yet.
 
-before_save, after_save, before_create, after_create, before_update, after_update,
-before_destroy, after_destroy
+The block supports a parameter, that will be filled with the object instance that sent the
+update notification to the observers.
 
 
 == Observers for DataMapper Resources
@@ -92,4 +120,7 @@ to them using the notify_observers method:
   end
 
   MyModelObserver.instance
-  MyModel.new.do_something
\ No newline at end of file
+  MyModel.new.do_something
+  ---- output ----
+  Purge Old Data...
+  ---- output ----
\ No newline at end of file</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1,2 @@
-- Fill the TODO ;-)
+* Add support to observe class methods
+* Add more specs for observer blocks definitions and observable notifications
\ No newline at end of file</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -4,19 +4,11 @@ module DataMapper
       def self.included(base)
         base.instance_variable_set(&quot;@observers&quot;, [])
         base.extend ClassMethods
-        [:save, :create, :update, :destroy].each do |action|
-          base.before action do
-            base.notify_observers(&quot;before_#{action}&quot;, self)
-          end
-          base.after action do
-            base.notify_observers(&quot;after_#{action}&quot;, self)
-          end
-        end
       end
     
       module ClassMethods
         def add_observer(observer)
-          @observers &lt;&lt; observer
+          @observers &lt;&lt; observer unless @observers.include?(observer)
         end
       
         def delete_observer(observer)</diff>
      <filename>lib/dm-observers/observable.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,19 +5,65 @@ module DataMapper
     class Observer
       include Singleton
 
+      attr_reader :observed_class
+
       def initialize
-        observed_class.add_observer(self) unless observed_class.nil?
+        klass = inferred_observed_class
+        self.observed_class = klass if klass.is_a?(Class)
+      end
+      
+      def observed_class=(klass)
+        raise &quot;The observed class was already assigned: #{@observer_class.name}&quot; unless @observed_class.nil?
+        @observed_class = klass
+        @observed_class.add_observer(self)
+        attach_hooks
       end
 
-      # The class observed by default is inferred from the observer's class name:
-      #   assert_equal [Person], PersonObserver.observed_class
-      def observed_class
-        if observed_class_name = self.class.name.scan(/(.*)Observer/)[0]
-          eval(observed_class_name[0]) rescue nil
-        else
-          nil
+      def inferred_observed_class
+        eval(self.class.name.scan(/(.*)Observer/)[0][0]) rescue nil
+      end
+
+      def attach_hooks
+        self.class.hooks.each do |type, hooks|
+          hooks.each do |target_method, hook_methods|
+            hook_methods.each do |hook_method|
+              @observed_class.send(type, target_method) do
+                self.class.notify_observers(&quot;#{hook_method}&quot;, self)
+              end
+            end
+          end
         end
       end
+      
+      def self.hooks
+        @hooks ||= {}
+      end
+      
+      def self.before(target_method, &amp;block)
+        define_block_method(:before, target_method, &amp;block)
+      end
+      
+      def self.after(target_method, &amp;block)
+        define_block_method(:after, target_method, &amp;block)
+      end
+
+      # FIXME: This doesn't work
+      # def self.before_class_method(target_method, &amp;block)
+      #   define_block_method(:before_class_method, target_method, &amp;block)
+      # end
+      # 
+      # def self.after_class_method(target_method, &amp;block)
+      #   define_block_method(:after_class_method, target_method, &amp;block)
+      # end
+      
+      def self.define_block_method(type, target_method, &amp;block)
+        self.hooks[type] ||= {}
+        new_block_method = &quot;__#{self.name}_observer_hooks_#{self.instance_methods.select{|m| m =~ /__#{self.name}_observer_hooks_/}.size}&quot;
+        define_method(new_block_method, &amp;block)
+        self.hooks[type][target_method] ||= []
+        self.hooks[type][target_method] &lt;&lt; new_block_method
+      end
+
     end # class Observer
   end # module Observers
 end # module DataMapper
\ No newline at end of file</diff>
      <filename>lib/dm-observers/observer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,15 +28,37 @@ describe DataMapper::Observers::Observer do
       property :id, Integer, :key =&gt; true
     end
     
-    class MyModelObserver &lt; DataMapper::Observers::Observer
+    class MyModelObserver  &lt; DataMapper::Observers::Observer
+      before :save do |object|
+        puts &quot;before :save with object #{object.inspect}&quot;
+      end
+      
+      before :save do
+        puts &quot;before :save&quot;
+      end
+      
+      after :save do
+        puts &quot;after :save&quot;
+      end
+      
+      def before_save(object)
+        puts &quot;before_save with object #{object.inspect}&quot;
+      end
     end
+    class MyCustomObserver &lt; DataMapper::Observers::Observer; end
   end
   
-  it &quot;should be a singleton class&quot; do
-    MyModelObserver.should be_a_singleton_class
+  it &quot;should work&quot; do
+    MyModelObserver.instance
+    MyModel.new.save
   end
   
-  it &quot;should be added to the observed model automatically&quot; do
-    MyModel.should_receive(:add_observer).with(MyModelObserver.instance).once
-  end
+  it &quot;should attach a hook to the observed class for each before block&quot;
+  
+  it &quot;should attach a hook to the observed class for each after block&quot;
+  
+  it &quot;should attach a hook to the observed class for each before_class_method block&quot;
+  
+  it &quot;should attach a hook to the observed class for each after_class_method block&quot;
+
 end
\ No newline at end of file</diff>
      <filename>spec/integration/observer_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9366b64381a7c353a79c284c7908737029eca793</id>
    </parent>
  </parents>
  <author>
    <name>Carlos Paramio</name>
    <email>carlosparamio@gmail.com</email>
  </author>
  <url>http://github.com/carlosparamio/dm-observers/commit/8c174b5fe79361b27ff3133dc5e14a18a91c55aa</url>
  <id>8c174b5fe79361b27ff3133dc5e14a18a91c55aa</id>
  <committed-date>2008-06-05T13:51:04-07:00</committed-date>
  <authored-date>2008-06-05T13:51:04-07:00</authored-date>
  <message>Use before/save blocks to define observer hooks, generate dynamic methods for blocks, attach generated methods to observed class</message>
  <tree>fec987a8242d23866c685d150dfaba04ceb86550</tree>
  <committer>
    <name>Carlos Paramio</name>
    <email>carlosparamio@gmail.com</email>
  </committer>
</commit>
