rulebook 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -29,11 +29,11 @@ The format is _back_ to what it was before 0.2.2!
29
29
 
30
30
  ## How It Works
31
31
 
32
- When you call the `rules` method in a class, it defines the constant `INSTANCE_RULEBOOK` and sets it to a new `RuleBook` instance; but only if the constant wasn't already defined. This way, it only defines the constant the first time you call the `rules` method.
32
+ When you call the `rule` method in a class, it defines the constant `INSTANCE_RULEBOOK` and sets it to a new `RuleBook` instance; but only if the constant wasn't already defined. This way, it only defines the constant the first time you call the `rule` method.
33
33
 
34
- When the first time `rules` is called in a class, we also include the `RuleBook::InstanceMethods` module which overrides the classes `method_missing`. So when you call an undefined method on your class's instance, we will try to match the method against the rules you've defined in `INSTANCE_RULEBOOK`.
34
+ When the first time `rule` is called in a class, we also include the `RuleBook::IncludeMethods` module which overrides the classes `method_missing`. So when you call an undefined method on your class's instance, we will try to match the method against the rules you've defined in `INSTANCE_RULEBOOK`.
35
35
 
36
- There is also a method called `class_rules` which does the same as rules does, only it defines the `CLASS_RULEBOOK` constance in the class; which is a different `RuleBook` instance. The first time `class_rules` is called, it extends the class with the `RuleBook::ClassMethods` module, which also contains a `method_missing` method.
36
+ There is also a method called `class_rule` which does the same as rules does, only it defines the `CLASS_RULEBOOK` constance in the class; which is a different `RuleBook` instance. The first time `class_rules` is called, it extends the class with the `RuleBook::ExtendMethods` module, which also contains a `method_missing` method.
37
37
 
38
38
  ## Better Example
39
39
 
@@ -126,7 +126,16 @@ Since 0.2 you can call the class methods `rules` and `class_rules` to wrap your
126
126
  rule(...){}
127
127
  end
128
128
 
129
- The result is exactly the same.
129
+ The result is exactly the same. These are also callable from inside the class.
130
+
131
+ class Car
132
+ rules do
133
+ rule(...){}
134
+ end
135
+ class_rules do
136
+ rule(...){}
137
+ end
138
+ end
130
139
 
131
140
  #### There are more examples in the examples and [test][1] directories and [Rubular][2] is a great place to test your Regexp.
132
141
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
data/lib/rulebook.rb CHANGED
@@ -1,116 +1,116 @@
1
- class RuleBook
2
- class Rule
3
- attr :what_to_capture, :block
4
-
5
- def initialize(what_to_capture, &block)
6
- raise(TypeError, 'what_to_capture must be of type Regexp') \
7
- unless what_to_capture.is_a?(Regexp)
8
-
9
- @what_to_capture, @block = what_to_capture, block
10
- end
11
-
12
- def matches_against?(query)
13
- !match_against(query).nil?
14
- end
15
-
16
- def match_against(query)
17
- query.to_s.match(@what_to_capture)
18
- end
19
- end
20
- end
21
-
22
- class RuleBook
23
- attr :rules
24
-
25
- def initialize
26
- @rules = []
27
- end
28
-
29
- def rule(what_to_capture, &block)
30
- rule = Rule.new(what_to_capture, &block)
31
- @rules << rule
32
- rule
33
- end
34
-
35
- def find_rules_that_match_against(query)
36
- @rules.find_all { |rule| !query.to_s.match(rule.what_to_capture).nil? }
37
- end
38
- end
39
-
40
- class RuleBook
41
- module IncludeMethods
42
- def method_missing(meth, *args, &block)
43
- rulebook = self.class.const_get('INSTANCE_RULEBOOK')
44
- rules = rulebook.find_rules_that_match_against(meth)
45
-
46
- unless rules.nil? || rules.empty?
47
- rule = rules.first
48
- match = rule.match_against(meth)
49
- instance_exec(*match.captures, *args, &rule.block)
50
- else
51
- super
52
- end
53
- end
54
- end
55
-
56
- module ExtendMethods
57
- def method_missing(meth, *args, &block)
58
- rulebook = const_get('CLASS_NOTEBOOK')
59
- rules = rulebook.find_rules_that_match_against(meth)
60
-
61
- unless rules.nil?
62
- rule = rules.first
63
- match = rule.match_against(meth)
64
- class_exec(*match.captures, *args, &rule.block)
65
- else
66
- super
67
- end
68
- end
69
- end
70
- end
71
-
72
- class Module
73
- def rule(what_to_capture, &block)
74
- raise(ArgumentError, 'rules must have a block') unless block_given?
75
-
76
- setup_rulebook('INSTANCE_RULEBOOK', :include)
77
- const_get('INSTANCE_RULEBOOK').rule(what_to_capture, &block)
78
- end
79
-
80
- def class_rule(what_to_capture, &block)
81
- raise(ArgumentError, 'class_rules must have a block') unless block_given?
82
-
83
- setup_rulebook('CLASS_NOTEBOOK', :extend)
84
- const_get('CLASS_NOTEBOOK').rule(what_to_capture, &block)
85
- end
86
-
87
- def rules(&block)
88
- raise(ArgumentError, 'rules must have a block') unless block_given?
89
-
90
- setup_rulebook('INSTANCE_RULEBOOK', :include)
91
- const_get('INSTANCE_RULEBOOK').instance_eval(&block)
92
- const_get('INSTANCE_RULEBOOK')
93
- end
94
-
95
- def class_rules(&block)
96
- raise(ArgumentError, 'class_rules must have a block') unless block_given?
97
-
98
- setup_rulebook('CLASS_NOTEBOOK', :extend)
99
- const_get('CLASS_NOTEBOOK').instance_eval(&block)
100
- const_get('CLASS_NOTEBOOK')
101
- end
102
-
103
- private
104
-
105
- def setup_rulebook(rulebook_constant, extend_or_include)
106
- raise(ArgumentError, 'extend_or_include must be :extend or :include') \
107
- unless [:extend, :include].include?(extend_or_include)
108
-
109
- unless const_defined?(rulebook_constant)
110
- const_set(rulebook_constant, RuleBook.new)
111
-
112
- module_name = extend_or_include.to_s.capitalize + 'Methods'
113
- send(extend_or_include, RuleBook.const_get(module_name))
114
- end
115
- end
116
- end
1
+ class RuleBook
2
+ class Rule
3
+ attr_accessor :what_to_capture, :block
4
+
5
+ def initialize(what_to_capture, &block)
6
+ raise(TypeError, 'what_to_capture must be of type Regexp') \
7
+ unless what_to_capture.is_a?(Regexp)
8
+
9
+ @what_to_capture, @block = what_to_capture, block
10
+ end
11
+
12
+ def matches_against?(query)
13
+ !match_against(query).nil?
14
+ end
15
+
16
+ def match_against(query)
17
+ query.to_s.match(@what_to_capture)
18
+ end
19
+ end
20
+ end
21
+
22
+ class RuleBook
23
+ attr_accessor :rules
24
+
25
+ def initialize
26
+ @rules = []
27
+ end
28
+
29
+ def rule(what_to_capture, &block)
30
+ rule = Rule.new(what_to_capture, &block)
31
+ @rules << rule
32
+ rule
33
+ end
34
+
35
+ def find_rules_that_match_against(query)
36
+ @rules.find_all { |rule| !query.to_s.match(rule.what_to_capture).nil? }
37
+ end
38
+ end
39
+
40
+ class RuleBook
41
+ module IncludeMethods
42
+ def method_missing(meth, *args, &block)
43
+ rulebook = self.class.const_get('INSTANCE_RULEBOOK')
44
+ rules = rulebook.find_rules_that_match_against(meth)
45
+
46
+ unless rules.nil? || rules.empty?
47
+ rule = rules.first
48
+ match = rule.match_against(meth)
49
+ instance_exec(*(match.captures||[] + args)[0...rule.block.arity], &rule.block)
50
+ else
51
+ super
52
+ end
53
+ end
54
+ end
55
+
56
+ module ExtendMethods
57
+ def method_missing(meth, *args, &block)
58
+ rulebook = const_get('CLASS_NOTEBOOK')
59
+ rules = rulebook.find_rules_that_match_against(meth)
60
+
61
+ unless rules.nil?
62
+ rule = rules.first
63
+ match = rule.match_against(meth)
64
+ class_exec(*(match.captures||[] + args)[0...rule.block.arity], &rule.block)
65
+ else
66
+ super
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ class Module
73
+ def rule(what_to_capture, &block)
74
+ raise(ArgumentError, 'rules must have a block') unless block_given?
75
+
76
+ setup_rulebook('INSTANCE_RULEBOOK', :include)
77
+ const_get('INSTANCE_RULEBOOK').rule(what_to_capture, &block)
78
+ end
79
+
80
+ def class_rule(what_to_capture, &block)
81
+ raise(ArgumentError, 'class_rules must have a block') unless block_given?
82
+
83
+ setup_rulebook('CLASS_NOTEBOOK', :extend)
84
+ const_get('CLASS_NOTEBOOK').rule(what_to_capture, &block)
85
+ end
86
+
87
+ def rules(&block)
88
+ raise(ArgumentError, 'rules must have a block') unless block_given?
89
+
90
+ setup_rulebook('INSTANCE_RULEBOOK', :include)
91
+ const_get('INSTANCE_RULEBOOK').instance_eval(&block)
92
+ const_get('INSTANCE_RULEBOOK')
93
+ end
94
+
95
+ def class_rules(&block)
96
+ raise(ArgumentError, 'class_rules must have a block') unless block_given?
97
+
98
+ setup_rulebook('CLASS_NOTEBOOK', :extend)
99
+ const_get('CLASS_NOTEBOOK').instance_eval(&block)
100
+ const_get('CLASS_NOTEBOOK')
101
+ end
102
+
103
+ private
104
+
105
+ def setup_rulebook(rulebook_constant, extend_or_include)
106
+ raise(ArgumentError, 'extend_or_include must be :extend or :include') \
107
+ unless [:extend, :include].include?(extend_or_include)
108
+
109
+ unless const_defined?(rulebook_constant)
110
+ const_set(rulebook_constant, RuleBook.new)
111
+
112
+ module_name = extend_or_include.to_s.capitalize + 'Methods'
113
+ send(extend_or_include, RuleBook.const_get(module_name))
114
+ end
115
+ end
116
+ end
data/rulebook.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rulebook}
8
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ryan Lewis"]
12
- s.date = %q{2010-04-29}
12
+ s.date = %q{2010-05-01}
13
13
  s.description = %q{Lets you define methods with regex for dynamic methods}
14
14
  s.email = %q{c00lryguy@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "test/helper.rb",
31
31
  "test/test_chevy.rb",
32
32
  "test/test_class_methods.rb",
33
+ "test/test_rules.rb",
33
34
  "test/test_ryguy.rb",
34
35
  "test/test_user.rb"
35
36
  ]
data/test/test_chevy.rb CHANGED
@@ -1,69 +1,69 @@
1
- require 'helper'
2
-
3
- class TestChevy < Test::Unit::TestCase
4
- class Engine
5
- attr :state
6
-
7
- def initialize
8
- @state = "off"
9
- end
10
-
11
- rules do
12
- rule(/is_(.*)/) do |state|
13
- @state = state.gsub(/_/, " ")
14
- end
15
- end
16
- end
17
-
18
- context 'A Chevy engine checked with #state_is?' do
19
- setup do
20
- @chevy = Engine.new
21
- class << @chevy
22
- def state_is?(state)
23
- @state == state
24
- end
25
- end
26
- end
27
-
28
- should 'be off' do
29
- assert @chevy.state_is?('off')
30
- end
31
-
32
- should 'be idling' do
33
- @chevy.is_idling
34
- assert @chevy.state_is?('idling')
35
- end
36
-
37
- should 'be broken as usual' do
38
- @chevy.is_broken_as_usual
39
- assert @chevy.state_is?('broken as usual')
40
- end
41
- end
42
-
43
- context 'A Chevy engine checked with custom rule' do
44
- setup do
45
- @chevy = Engine.new
46
- class << @chevy
47
- rules do
48
- rule(/is_(.*)?/) do |state|
49
- @state == state
50
- end
51
- end
52
- end
53
- end
54
-
55
- should 'be off' do
56
- assert @chevy.is_off?
57
- end
58
-
59
- should 'be idling' do
60
- @chevy.is_idling
61
- assert @chevy.is_idling?
62
- end
63
-
64
- should 'be broken as usual' do
65
- @chevy.is_broken_as_usual
66
- assert @chevy.is_broken_as_usual?
67
- end
68
- end
69
- end
1
+ require 'helper'
2
+
3
+ class TestChevy < Test::Unit::TestCase
4
+ class Engine
5
+ attr_accessor :state
6
+
7
+ def initialize
8
+ @state = "off"
9
+ end
10
+
11
+ rules do
12
+ rule(/is_(.*)/) do |state|
13
+ @state = state.gsub(/_/, " ")
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'A Chevy engine checked with #state_is?' do
19
+ setup do
20
+ @chevy = Engine.new
21
+ class << @chevy
22
+ def state_is?(state)
23
+ @state == state
24
+ end
25
+ end
26
+ end
27
+
28
+ should 'be off' do
29
+ assert @chevy.state_is?('off')
30
+ end
31
+
32
+ should 'be idling' do
33
+ @chevy.is_idling
34
+ assert @chevy.state_is?('idling')
35
+ end
36
+
37
+ should 'be broken as usual' do
38
+ @chevy.is_broken_as_usual
39
+ assert @chevy.state_is?('broken as usual')
40
+ end
41
+ end
42
+
43
+ context 'A Chevy engine checked with custom rule' do
44
+ setup do
45
+ @chevy = Engine.new
46
+ class << @chevy
47
+ rules do
48
+ rule(/is_(.*)?/) do |state|
49
+ @state == state
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ should 'be off' do
56
+ assert @chevy.is_off?
57
+ end
58
+
59
+ should 'be idling' do
60
+ @chevy.is_idling
61
+ assert @chevy.is_idling?
62
+ end
63
+
64
+ should 'be broken as usual' do
65
+ @chevy.is_broken_as_usual
66
+ assert @chevy.is_broken_as_usual?
67
+ end
68
+ end
69
+ end
@@ -1,53 +1,53 @@
1
- require 'helper'
2
-
3
- class TestClassMethods < Test::Unit::TestCase
4
- class Car
5
- attr :make, :model
6
-
7
- def initialize(make, model)
8
- @make, @model = make, model
9
- end
10
-
11
- class_rules do
12
- rule(/new_([a-z]+)_(.+)/) do |make, model|
13
-
14
- make.capitalize!
15
- model = model.split('_').inject(''){ |result, word|
16
- result << word.capitalize + ' '
17
- }.strip
18
- new(make, model)
19
- end
20
- end
21
- end
22
-
23
- should 'be a Ford F150' do
24
- @car = Car.new_ford_f150
25
- assert_equal @car.make, 'Ford'
26
- assert_equal @car.model, 'F150'
27
- end
28
-
29
- should 'be a Ford Mustang' do
30
- @car = Car.new_ford_mustang
31
- assert_equal @car.make, 'Ford'
32
- assert_equal @car.model, 'Mustang'
33
- end
34
-
35
- should 'be a Pontiac GTO' do
36
- @car = Car.new_pontiac_gto
37
- @car.model.upcase!
38
- assert_equal @car.make, 'Pontiac'
39
- assert_equal @car.model, 'GTO'
40
- end
41
-
42
- should 'be a Toyota Camry' do
43
- @car = Car.new_toyota_camry
44
- assert_equal @car.make, 'Toyota'
45
- assert_equal @car.model, 'Camry'
46
- end
47
-
48
- should 'be a Hyundai Santa Fe' do
49
- @car = Car.new_hyundai_santa_fe
50
- assert_equal @car.make, 'Hyundai'
51
- assert_equal 'Santa Fe', @car.model
52
- end
53
- end
1
+ require 'helper'
2
+
3
+ class TestClassMethods < Test::Unit::TestCase
4
+ class Car
5
+ attr_accessor :make, :model
6
+
7
+ def initialize(make, model)
8
+ @make, @model = make, model
9
+ end
10
+
11
+ class_rules do
12
+ rule(/new_([a-z]+)_(.+)/) do |make, model|
13
+
14
+ make.capitalize!
15
+ model = model.split('_').inject(''){ |result, word|
16
+ result << word.capitalize + ' '
17
+ }.strip
18
+ new(make, model)
19
+ end
20
+ end
21
+ end
22
+
23
+ should 'be a Ford F150' do
24
+ @car = Car.new_ford_f150
25
+ assert_equal @car.make, 'Ford'
26
+ assert_equal @car.model, 'F150'
27
+ end
28
+
29
+ should 'be a Ford Mustang' do
30
+ @car = Car.new_ford_mustang
31
+ assert_equal @car.make, 'Ford'
32
+ assert_equal @car.model, 'Mustang'
33
+ end
34
+
35
+ should 'be a Pontiac GTO' do
36
+ @car = Car.new_pontiac_gto
37
+ @car.model.upcase!
38
+ assert_equal @car.make, 'Pontiac'
39
+ assert_equal @car.model, 'GTO'
40
+ end
41
+
42
+ should 'be a Toyota Camry' do
43
+ @car = Car.new_toyota_camry
44
+ assert_equal @car.make, 'Toyota'
45
+ assert_equal @car.model, 'Camry'
46
+ end
47
+
48
+ should 'be a Hyundai Santa Fe' do
49
+ @car = Car.new_hyundai_santa_fe
50
+ assert_equal @car.make, 'Hyundai'
51
+ assert_equal 'Santa Fe', @car.model
52
+ end
53
+ end
data/test/test_ryguy.rb CHANGED
@@ -1,45 +1,45 @@
1
- require 'helper'
2
-
3
- class TestRyguy < Test::Unit::TestCase
4
- class Ryguy
5
- attr :nouns, :adjectives
6
-
7
- rules do
8
- rule(/is_a_(.*)/) do |noun|
9
- @nouns ||= []
10
- @nouns << noun.gsub(/_/, ' ')
11
- end
12
-
13
- rule(/is_(.*)/) do |adjective|
14
- @adjectives ||= []
15
- @adjectives << adjective.gsub(/_/, ' ')
16
- end
17
- end
18
- end
19
-
20
- context 'Ryguy' do
21
- setup do
22
- @ryguy = Ryguy.new
23
- @ryguy.is_awesome
24
- @ryguy.is_a_bear
25
- @ryguy.is_superfly
26
- @ryguy.is_a_programmer
27
- @ryguy.is_fantastic
28
- @ryguy.is_a_master_of_the_ancient_chinese_art_of_karate
29
- end
30
-
31
- should 'be awesome, superfly, and fantastic' do
32
- assert_same_elements(
33
- ['awesome', 'superfly', 'fantastic'],
34
- @ryguy.adjectives
35
- )
36
- end
37
-
38
- should 'be a bear, a programmer, and a master of karate' do
39
- assert_same_elements(
40
- ['bear', 'programmer', 'master of the ancient chinese art of karate'],
41
- @ryguy.nouns
42
- )
43
- end
44
- end
45
- end
1
+ require 'helper'
2
+
3
+ class TestRyguy < Test::Unit::TestCase
4
+ class Ryguy
5
+ attr_accessor :nouns, :adjectives
6
+
7
+ rules do
8
+ rule(/is_a_(.*)/) do |noun|
9
+ @nouns ||= []
10
+ @nouns << noun.gsub(/_/, ' ')
11
+ end
12
+
13
+ rule(/is_(.*)/) do |adjective|
14
+ @adjectives ||= []
15
+ @adjectives << adjective.gsub(/_/, ' ')
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'Ryguy' do
21
+ setup do
22
+ @ryguy = Ryguy.new
23
+ @ryguy.is_awesome
24
+ @ryguy.is_a_bear
25
+ @ryguy.is_superfly
26
+ @ryguy.is_a_programmer
27
+ @ryguy.is_fantastic
28
+ @ryguy.is_a_master_of_the_ancient_chinese_art_of_karate
29
+ end
30
+
31
+ should 'be awesome, superfly, and fantastic' do
32
+ assert_same_elements(
33
+ ['awesome', 'superfly', 'fantastic'],
34
+ @ryguy.adjectives
35
+ )
36
+ end
37
+
38
+ should 'be a bear, a programmer, and a master of karate' do
39
+ assert_same_elements(
40
+ ['bear', 'programmer', 'master of the ancient chinese art of karate'],
41
+ @ryguy.nouns
42
+ )
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 0
9
- version: 0.3.0
8
+ - 1
9
+ version: 0.3.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ryan Lewis
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-29 00:00:00 -04:00
17
+ date: 2010-05-01 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -41,6 +41,7 @@ files:
41
41
  - test/helper.rb
42
42
  - test/test_chevy.rb
43
43
  - test/test_class_methods.rb
44
+ - test/test_rules.rb
44
45
  - test/test_ryguy.rb
45
46
  - test/test_user.rb
46
47
  has_rdoc: true