rconditions 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. data/README +117 -2
  2. data/lib/rconditions.rb +23 -128
  3. metadata +11 -5
data/README CHANGED
@@ -1,5 +1,120 @@
1
1
  = RConditions
2
2
 
3
- RConditions generates a bang method (for example, <tt>Array#empty!</tt>) for each predicate method (for example, <tt>Array#empty?</tt>). The bang method will return true if the predicate method returns true, otherwise it will throw an exception. The exception will include auto-generated modules that give information which predicate methods passed or failed in the bang method's execution.
3
+ RConditions generates a bang method (for example, <tt>Array#empty!</tt>)
4
+ for each predicate method (for example, <tt>Array#empty?</tt>). The bang
5
+ method will pass if the predicate method passes, otherwise it
6
+ will throw an exception. The exception will include auto-generated modules
7
+ that give information which predicate methods passed or failed in the bang
8
+ method's execution.
4
9
 
5
- For more information, see the roc or ri documentation of the module RConditions.
10
+ == A Simple Example
11
+
12
+ require "rconditions"
13
+
14
+ begin
15
+ [1,2].empty!
16
+ rescue Array::NotEmptyError => e
17
+ p e
18
+ end
19
+
20
+ # => #<Exception: Array::NotEmptyError>
21
+
22
+ The raised exception includes a module defined on the class where the method is defined. The module's name is derived from the predicate method's name.
23
+
24
+ == A More Complicated Example
25
+
26
+ require "rconditions"
27
+
28
+ class Posting
29
+ attr_writer :spam, :active
30
+
31
+ def spam?
32
+ @spam
33
+ end
34
+
35
+ def active?
36
+ @active
37
+ end
38
+
39
+ def visible?
40
+ !spam? && active?
41
+ end
42
+ end
43
+
44
+ class User
45
+ attr_writer :admin
46
+
47
+ def admin?
48
+ @admin
49
+ end
50
+
51
+ def can_view_posting?(posting)
52
+ admin? || posting.visible?
53
+ end
54
+ end
55
+
56
+ user = User.new
57
+ user.admin = false
58
+
59
+ posting = Posting.new
60
+ posting.active = false
61
+ posting.spam = true
62
+
63
+ begin
64
+ user.can_view_posting!(posting)
65
+ rescue Posting::SpamError => e
66
+ p e
67
+ rescue Posting::NotActiveError
68
+ puts "should not get here"
69
+ end
70
+
71
+ # => #<Exception: User::NotAdminError, Posting::SpamError,
72
+ # Posting::NotVisibleError, User::NotCanViewPostingError>
73
+
74
+ As you can see, the exception includes modules for each of the evaluated
75
+ predicate methods: <tt>User#can_view_posting!(posting)</tt> in the context
76
+ above called <tt>User#can_view_posting?(posting)</tt>, which called
77
+ <tt>User#admin?</tt> and <tt>Posting#can_view_posting?</tt>, which called
78
+ <tt>Posting#spam?</tt>.
79
+
80
+ The results were
81
+
82
+ * <tt>User#admin? # => false</tt>
83
+ * <tt>Posting#spam? # => true</tt>
84
+ * <tt>Posting#can_view_posting? # => false</tt>
85
+ * <tt>User#can_view_posting? # => false</tt>
86
+
87
+ so the included exception modules are
88
+
89
+ * <tt>User::NotAdminError</tt>
90
+ * <tt>Posting::SpamError</tt>
91
+ * <tt>Posting::NotCanViewPostingError</tt>
92
+ * <tt>User::NotCanViewPostingError</tt>
93
+
94
+ == Performance
95
+
96
+ As almost all predicate methods are extended by default, RConditions carries
97
+ a performance penalty which varies with the number of calls to predicate
98
+ methods. A simple test setup using mongrel/rails was slowed down by 10-20%
99
+ by adding <tt>require "rconditions"</tt> to the bottom of its
100
+ <tt>enviroment.rb</tt>.
101
+
102
+ The performance penalty can be avoided by applying RConditions only to new
103
+ methods, that is, methods defined after <tt>require "rconditions"</tt>. To
104
+ achieve this, set <tt>RCONDITIONS_ONLY_FOR_NEW_METHODS = true</tt> before
105
+ the require call. Our test setup had no measurable slowdown afterwards.
106
+
107
+ == Limitations
108
+
109
+ * RConditions currently only support predicate methods starting with a letter
110
+ and containing only word characters except the question mark at the end.
111
+ * RConditions does not support singleton methods. These includes all class
112
+ methods.
113
+
114
+ == License
115
+
116
+ RConditions is released under the MIT license.
117
+
118
+ == Authors
119
+
120
+ RConditions is written by Norman Timmler and Tammo Freese.
data/lib/rconditions.rb CHANGED
@@ -1,122 +1,12 @@
1
- # = RConditions
2
- #
3
- # RConditions generates a bang method (for example, <tt>Array#empty!</tt>)
4
- # for each predicate method (for example, <tt>Array#empty?</tt>). The bang
5
- # method will return true if the predicate method returns true, otherwise it
6
- # will throw an exception. The exception will include auto-generated modules
7
- # that give information which predicate methods passed or failed in the bang
8
- # method's execution.
9
- #
10
- # == Example
11
- #
12
- # Here is a simple example. The raised exception includes a module defined
13
- # on the class where the method is defined:
14
- #
15
- # require "rconditions"
16
- #
17
- # begin
18
- # [1,2].empty!
19
- # rescue Array::NotEmptyError => e
20
- # p e
21
- # end
22
- #
23
- # # => #<Exception: Array::NotEmptyError>
24
- #
25
- # Here is a more complicated example:
26
- #
27
- # require "rconditions"
28
- #
29
- # class Posting
30
- # attr_writer :spam, :active
31
- #
32
- # def spam?
33
- # @spam
34
- # end
35
- #
36
- # def active?
37
- # @active
38
- # end
39
- #
40
- # def visible?
41
- # !spam? && active?
42
- # end
43
- # end
44
- #
45
- # class User
46
- # attr_writer :admin
47
- #
48
- # def admin?
49
- # @admin
50
- # end
51
- #
52
- # def can_view_posting?(posting)
53
- # admin? || posting.visible?
54
- # end
55
- # end
56
- #
57
- # user = User.new
58
- # user.admin = false
59
- #
60
- # posting = Posting.new
61
- # posting.active = false
62
- # posting.spam = true
63
- #
64
- # begin
65
- # user.can_view_posting!(posting)
66
- # rescue Posting::SpamError => e
67
- # p e
68
- # rescue Posting::NotActiveError
69
- # puts "should not get here"
70
- # end
71
- #
72
- # # => #<Exception: User::NotAdminError, Posting::SpamError,
73
- # # Posting::NotVisibleError, User::NotCanViewPostingError>
74
- #
75
- # As you can see, the exception includes modules for each of the evaluated
76
- # predicate methods: <tt>User#can_view_posting!(posting)</tt> in the context
77
- # above called <tt>User#can_view_posting?(posting)</tt>, which called
78
- # <tt>User#admin?</tt> and <tt>Posting#can_view_posting?</tt>, which called
79
- # <tt>Posting#spam?</tt>.
80
- #
81
- # The results were
82
- #
83
- # * <tt>User#admin? # => false</tt>
84
- # * <tt>Posting#spam? # => true</tt>
85
- # * <tt>Posting#can_view_posting? # => false</tt>
86
- # * <tt>User#can_view_posting? # => false</tt>
87
- #
88
- # so the included exception modules are
89
- #
90
- # * <tt>User::NotAdminError</tt>
91
- # * <tt>Posting::SpamError</tt>
92
- # * <tt>Posting::NotCanViewPostingError</tt>
93
- # * <tt>User::NotCanViewPostingError</tt>
94
- #
95
- # == Performance
96
- #
97
- # As almost all predicate methods are extended by default, RConditions carries
98
- # a performance penalty which varies with the number of calls to predicate
99
- # methods. A simple test setup using mongrel/rails was slowed down by 10-20%
100
- # by adding <tt>require "rconditions"</tt> to the bottom of its
101
- # <tt>enviroment.rb</tt>.
102
- #
103
- # The performance penalty can be avoided by applying RConditions only to new
104
- # methods, that is, methods defined after <tt>require "rconditions"</tt>. To
105
- # achieve this, set <tt>RCONDITIONS_ONLY_FOR_NEW_METHODS = true</tt> before
106
- # the require call. Our test setup had no measurable slowdown afterwards.
107
- #
108
- # == Known Limitations
109
- #
110
- # * RConditions does only support predicate methods starting with a letter and
111
- # containing only word characters except the question mark at the end.
112
- # * RConditions does not support singleton methods. These includes all class
113
- # methods.
1
+ # Holds RCondition's methods. You should never call these methods
2
+ # directly, as they are automatically called.
114
3
  module RConditions
115
4
  class << self
116
5
 
117
- # Extends the given predicate method and defines a bang method for it. You
118
- # should never call this method directly, it is called from
119
- # Module#method_added.
6
+ # Extends a given predicate method and defines a bang method for it. You
7
+ # should never call this method yourself, it is called either from
8
+ # RConditions#extend_predicate_methods_and_define_bang_methods, or from
9
+ # <tt>Module#method_added</tt> which is extended by RConditions.
120
10
  # * <tt>mod</tt> -- the module on which the method is defined.
121
11
  # * <tt>id</tt> -- the name of the method.
122
12
  def extend_predicate_method_and_define_bang_method(mod, id)
@@ -132,6 +22,19 @@ module RConditions
132
22
  end
133
23
  end
134
24
 
25
+ # Extends almost all predicate methods and defines bang methods for them.
26
+ # You should never call this method yourself, it is called automatically
27
+ # when RConditions is required. To prevent it from being called, set
28
+ # <tt>RCONDITIONS_ONLY_FOR_NEW_METHODS</tt> to <tt>true</tt> before
29
+ # requiring RConditions.
30
+ def extend_predicate_methods_and_define_bang_methods
31
+ ObjectSpace.each_object(Module) do |mod|
32
+ mod.instance_methods(false).each do |id|
33
+ RConditions.extend_predicate_method_and_define_bang_method(mod, id)
34
+ end
35
+ end
36
+ end
37
+
135
38
  def exception_modules #:nodoc:
136
39
  Thread.current[:rconditions_exception_modules]
137
40
  end
@@ -212,22 +115,14 @@ unless defined? RCONDITIONS_ONLY_FOR_NEW_METHODS
212
115
  end
213
116
 
214
117
  unless RCONDITIONS_ONLY_FOR_NEW_METHODS
215
- ObjectSpace.each_object(Module) do |mod|
216
- mod.instance_methods(false).each do |id|
217
- RConditions.extend_predicate_method_and_define_bang_method(mod, id)
218
- end
219
- end
118
+ RConditions.extend_predicate_methods_and_define_bang_methods
220
119
  end
221
-
222
- class Module
120
+
121
+ class Module #:nodoc:
223
122
  alias_method :method_added_without_rconditions, :method_added
224
123
  private :method_added_without_rconditions
225
124
 
226
- # To provide a bang method and exception modules for each predicate method,
227
- # RConditions hooks into <tt>method_added</tt>. An existing
228
- # <tt>method_added</tt> implementation will not be replaced, but executed
229
- # afterwards.
230
- def method_added(id)
125
+ def method_added(id) #:nodoc:
231
126
  RConditions.extend_predicate_method_and_define_bang_method(self, id)
232
127
  method_added_without_rconditions(id)
233
128
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: rconditions
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
6
+ version: 0.1.1
7
7
  date: 2007-09-27 00:00:00 +02:00
8
8
  summary: RConditions generates a bang method (for example, Array#empty!) for each predicate method (for example, Array#empty?). The bang method will return true if the predicate method returns true, otherwise it will throw an exception. The exception will include auto-generated modules that give information on predicate methods passed or failed in the bang method's execution.
9
9
  require_paths:
@@ -36,10 +36,16 @@ files:
36
36
  - MIT-LICENSE
37
37
  test_files:
38
38
  - test/rconditions_test.rb
39
- rdoc_options: []
40
-
41
- extra_rdoc_files: []
42
-
39
+ rdoc_options:
40
+ - --title
41
+ - RConditions RDoc Documentation
42
+ - --main
43
+ - README
44
+ - --charset
45
+ - utf-8
46
+ extra_rdoc_files:
47
+ - README
48
+ - MIT-LICENSE
43
49
  executables: []
44
50
 
45
51
  extensions: []