sentinel 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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