sentinel 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.textile CHANGED
@@ -14,9 +14,9 @@ First, install the gem:
14
14
  $ [sudo] gem install sentinel
15
15
  </pre>
16
16
 
17
- Then, add it as a dependency in your code using your favorite way (a simple require or mechanisms the bundler gem).
17
+ Then, add it as a dependency in your code using your favorite way (a simple require or mechanisms like the bundler gem).
18
18
 
19
- To use it, first you'll need an observer class that responds to a method called *_notify_* (which can be a class or instance method). All the observed method's arguments will be passed to this method, hence the _args_ splat.
19
+ To use it, first you'll need an observer class that responds to a class method called *_notify_*. All the observed method's arguments will be passed to this method, hence the _args_ splat.
20
20
 
21
21
  <pre>
22
22
  class MyObserver
@@ -26,12 +26,25 @@ class MyObserver
26
26
  end
27
27
  </pre>
28
28
 
29
- Then, simple include the _Sentinel_ module in the class and declare the observer. Sentinel can observe both class and instance methods:
29
+ Then, simply include the _Sentinel_ module in the observer, setting up the desired class (or classes) and method (or methods) to be observed.
30
30
 
31
31
  <pre>
32
- class MyClass
32
+ class MyObserver
33
33
  include Sentinel
34
34
 
35
+ observe MyClass, :instance_method
36
+ observe MyClass, :class_method, :class_method => true #to observe a class method
37
+
38
+ def self.notify(*args)
39
+ puts "Do your thing!"
40
+ end
41
+ end
42
+ </pre>
43
+
44
+ As you can see, Sentinel can observe both class and instance methods. Now, our actual class:
45
+
46
+ <pre>
47
+ class MyClass
35
48
  def instance_method
36
49
  puts "Hi from the instance method!"
37
50
  end
@@ -39,25 +52,13 @@ class MyClass
39
52
  def self.class_method
40
53
  puts "Hi from the class method!"
41
54
  end
42
-
43
- observe :instance_method, :notify => MyObserver
44
- observe :class_method, :notify => MyObserver, :class_method => true #to observe a class method
45
55
  end
46
56
  </pre>
47
57
 
48
- If we wanted to use instances of the Observer instead of the class itself, the declarations would be:
49
-
50
- <pre>
51
- observe :instance_method, :notify => MyObserver.new
52
- observe :class_method, :notify => MyObserver.new, :class_method => true #to observe a class method
53
- </pre>
54
-
55
- In summary, any object that responds to *_notify_* will be accepted.
56
-
57
- And... that's it! Every time the observed method is called, the _notify_ method from the defined Observer will be called *before* it, then it will run normally.
58
+ And... that's it! Every time the observed method is called, the _notify_ method from the defined _observer class_ will be called *before* it, then it will run normally.
58
59
 
59
60
  h2. Note on Patches/Pull Requests
60
-
61
+
61
62
  * Fork the project.
62
63
  * Make your feature addition or bug fix.
63
64
  * Add tests for it. This is important so I don't break it in a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/lib/metaid.rb ADDED
@@ -0,0 +1,17 @@
1
+ # Code by why_the_lucky_stiff
2
+
3
+ class Object
4
+ # The hidden singleton lurks behind everyone
5
+ def metaclass; class << self; self; end; end
6
+ def meta_eval &blk; metaclass.instance_eval &blk; end
7
+
8
+ # Adds methods to a metaclass
9
+ def meta_def name, &blk
10
+ meta_eval { define_method name, &blk }
11
+ end
12
+
13
+ # Defines an instance method within a class
14
+ def class_def name, &blk
15
+ class_eval { define_method name, &blk }
16
+ end
17
+ end
data/lib/sentinel.rb CHANGED
@@ -1,33 +1,30 @@
1
+ require "metaid"
2
+
1
3
  module Sentinel
2
4
  def self.included(base)
3
5
  base.extend(ClassMethods)
4
6
  end
5
-
7
+
6
8
  module ClassMethods
7
- def observe(method_name, options = {})
8
- unless options[:notify]
9
- raise ArgumentError.new("You should provide the :notify option")
10
- end
9
+ def observe(class_name, method_name, options = {})
10
+ sentinel = self
11
+
11
12
  body = <<-CODE
12
13
  define_method "#{method_name}_with_observer" do |*args|
13
- options[:notify].notify(*args)
14
+ sentinel.notify(*args)
14
15
  self.send("#{method_name}_without_observer", *args)
15
16
  end
16
17
 
17
18
  alias_method "#{method_name}_without_observer", method_name
18
19
  alias_method method_name, "#{method_name}_with_observer"
19
20
  CODE
20
-
21
- if options[:class_method]
22
-
23
- metaclass = class << self; self; end
24
21
 
25
- metaclass.instance_eval do
22
+ if options[:class_method]
23
+ class_name.meta_eval do
26
24
  eval body
27
25
  end
28
-
29
26
  else
30
- eval body
27
+ class_name.send(:class_eval, body)
31
28
  end
32
29
  end
33
30
  end
data/sentinel.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sentinel}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Lucas H\303\272ngaro"]
12
- s.date = %q{2010-01-19}
12
+ s.date = %q{2010-03-02}
13
13
  s.description = %q{Transparent (unobtrusive) Observers for your Ruby code}
14
14
  s.email = %q{lucashungaro@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -23,10 +23,11 @@ Gem::Specification.new do |s|
23
23
  "README.textile",
24
24
  "Rakefile",
25
25
  "VERSION",
26
+ "lib/metaid.rb",
26
27
  "lib/sentinel.rb",
27
28
  "sentinel.gemspec",
28
29
  "spec/fixtures/my_observer.rb",
29
- "spec/fixtures/subject.rb",
30
+ "spec/fixtures/sentinel_subject.rb",
30
31
  "spec/sentinel_spec.rb",
31
32
  "spec/spec.opts",
32
33
  "spec/spec_helper.rb"
@@ -34,11 +35,11 @@ Gem::Specification.new do |s|
34
35
  s.homepage = %q{http://github.com/lucashungaro/sentinel}
35
36
  s.rdoc_options = ["--charset=UTF-8"]
36
37
  s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.3.5}
38
+ s.rubygems_version = %q{1.3.6}
38
39
  s.summary = %q{Transparent (unobtrusive) Observers for your Ruby code}
39
40
  s.test_files = [
40
41
  "spec/fixtures/my_observer.rb",
41
- "spec/fixtures/subject.rb",
42
+ "spec/fixtures/sentinel_subject.rb",
42
43
  "spec/sentinel_spec.rb",
43
44
  "spec/spec_helper.rb"
44
45
  ]
@@ -1,4 +1,4 @@
1
- class Subject
1
+ class SentinelSubject
2
2
  def instance_method
3
3
  "hi from instance method!"
4
4
  end
@@ -1,46 +1,46 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
  require File.expand_path(File.dirname(__FILE__) + '/fixtures/my_observer')
3
- require File.expand_path(File.dirname(__FILE__) + '/fixtures/subject')
3
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/sentinel_subject')
4
4
 
5
5
  describe Sentinel, "defining an observer for a method" do
6
6
  before(:all) do
7
- Subject.send(:include, Sentinel)
7
+ MyObserver.send(:include, Sentinel)
8
8
  end
9
9
 
10
10
  context "with the minimum required options" do
11
11
  it "should notify the specified Observer when calling a class method" do
12
- Subject.send(:observe, :instance_method, :notify => MyObserver)
12
+ MyObserver.send(:observe, SentinelSubject, :instance_method)
13
13
  MyObserver.expects(:notify)
14
14
 
15
- Subject.new.instance_method
15
+ SentinelSubject.new.instance_method
16
16
  end
17
17
 
18
18
  it "should notify the specified Observer when calling an instance method" do
19
- Subject.send(:observe, :class_method, :notify => MyObserver, :class_method => true)
19
+ MyObserver.send(:observe, SentinelSubject, :class_method, :class_method => true)
20
20
  MyObserver.expects(:notify)
21
21
 
22
- Subject.class_method
22
+ SentinelSubject.class_method
23
23
  end
24
24
 
25
25
  it "should not modify the observed methods output" do
26
- Subject.send(:observe, :class_returning_something, :notify => MyObserver, :class_method => true)
27
- Subject.send(:observe, :instance_returning_something, :notify => MyObserver)
26
+ MyObserver.send(:observe, SentinelSubject, :class_returning_something, :class_method => true)
27
+ MyObserver.send(:observe, SentinelSubject, :instance_returning_something)
28
28
 
29
29
  MyObserver.expects(:notify).twice
30
30
 
31
- Subject.class_returning_something.should == 42
32
- Subject.new.instance_returning_something.should == 42
31
+ SentinelSubject.class_returning_something.should == 42
32
+ SentinelSubject.new.instance_returning_something.should == 42
33
33
  end
34
34
 
35
35
  context "observing methods with parameters" do
36
36
  it "should pass all parameters of the observed methods to the Observer" do
37
- Subject.send(:observe, :class_method_with_params, :notify => MyObserver, :class_method => true)
38
- Subject.send(:observe, :instance_method_with_params, :notify => MyObserver)
37
+ MyObserver.send(:observe, SentinelSubject, :class_method_with_params, :class_method => true)
38
+ MyObserver.send(:observe, SentinelSubject, :instance_method_with_params)
39
39
 
40
40
  MyObserver.expects(:notify).twice.with("texto", 1)
41
41
 
42
- Subject.class_method_with_params("texto", 1)
43
- Subject.new.instance_method_with_params("texto", 1)
42
+ SentinelSubject.class_method_with_params("texto", 1)
43
+ SentinelSubject.new.instance_method_with_params("texto", 1)
44
44
  end
45
45
  end
46
46
  end
@@ -48,16 +48,16 @@ describe Sentinel, "defining an observer for a method" do
48
48
  context "without the minimum required options" do
49
49
  it "should raise ArgumentError when the observer of an instance method is not defined" do
50
50
  MyObserver.expects(:notify).never
51
- Subject.expects(:observe).raises(ArgumentError)
51
+ SentinelSubject.expects(:observe).raises(ArgumentError)
52
52
 
53
- Subject.send(:observe, :instance_method) rescue nil
53
+ SentinelSubject.send(:observe, :instance_method) rescue nil
54
54
  end
55
55
 
56
56
  it "should raise ArgumentError when the observer of a class method is not defined" do
57
57
  MyObserver.expects(:notify).never
58
- Subject.expects(:observe).raises(ArgumentError)
58
+ SentinelSubject.expects(:observe).raises(ArgumentError)
59
59
 
60
- Subject.send(:observe, :class_method, :class_method => true) rescue nil
60
+ SentinelSubject.send(:observe, :class_method, :class_method => true) rescue nil
61
61
  end
62
62
  end
63
63
  end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentinel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - "Lucas H\xC3\xBAngaro"
@@ -9,29 +14,37 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-01-19 00:00:00 -02:00
17
+ date: 2010-03-02 00:00:00 -03:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: rspec
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
23
31
  version: 1.2.9
24
- version:
32
+ type: :development
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: mocha
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 9
44
+ - 8
33
45
  version: 0.9.8
34
- version:
46
+ type: :development
47
+ version_requirements: *id002
35
48
  description: Transparent (unobtrusive) Observers for your Ruby code
36
49
  email: lucashungaro@gmail.com
37
50
  executables: []
@@ -48,10 +61,11 @@ files:
48
61
  - README.textile
49
62
  - Rakefile
50
63
  - VERSION
64
+ - lib/metaid.rb
51
65
  - lib/sentinel.rb
52
66
  - sentinel.gemspec
53
67
  - spec/fixtures/my_observer.rb
54
- - spec/fixtures/subject.rb
68
+ - spec/fixtures/sentinel_subject.rb
55
69
  - spec/sentinel_spec.rb
56
70
  - spec/spec.opts
57
71
  - spec/spec_helper.rb
@@ -68,23 +82,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
82
  requirements:
69
83
  - - ">="
70
84
  - !ruby/object:Gem::Version
85
+ segments:
86
+ - 0
71
87
  version: "0"
72
- version:
73
88
  required_rubygems_version: !ruby/object:Gem::Requirement
74
89
  requirements:
75
90
  - - ">="
76
91
  - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
77
94
  version: "0"
78
- version:
79
95
  requirements: []
80
96
 
81
97
  rubyforge_project:
82
- rubygems_version: 1.3.5
98
+ rubygems_version: 1.3.6
83
99
  signing_key:
84
100
  specification_version: 3
85
101
  summary: Transparent (unobtrusive) Observers for your Ruby code
86
102
  test_files:
87
103
  - spec/fixtures/my_observer.rb
88
- - spec/fixtures/subject.rb
104
+ - spec/fixtures/sentinel_subject.rb
89
105
  - spec/sentinel_spec.rb
90
106
  - spec/spec_helper.rb