rconditions 0.1.0 → 0.1.1

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