rulebook 0.3.0 → 0.3.1

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.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