Class: Constraint::Shell
- Inherits:
-
Object
- Object
- Constraint::Shell
- Extended by:
- Helper
- Includes:
- Helper
- Defined in:
- lib/constraint.rb
Overview
If CONSTRAINT_DISABLE is set to true before loading this library, constraint checking is turned off.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#constrained_value ⇒ Object
readonly
The actual value that is covered by the Shell.
Attributes included from Helper
Class Method Summary collapse
- .inherited(subclass) ⇒ Object
-
.with_all_arguments_constrained(*methods) ⇒ Object
Wrap
methodsso that all arguments are filtered through #check_constraints. -
.with_arguments_constrained(*methods, &block) ⇒ Object
Wrap
methodsso that some arguments are filtered through #check_constraints. -
.without_constraints(*methods) ⇒ Object
Delegate
methodsto @constrained_value without taking any measures.
Instance Method Summary collapse
-
#check_constraints(object) ⇒ Object
Check if
objectcomplies with @constraints. - #clone ⇒ Object
- #dup ⇒ Object
-
#initialize(core = nil, predecessor = nil) ⇒ Shell
constructor
A new instance of Shell.
-
#method_missing(method, *args, &block) ⇒ Object
Delegate unknown methods to @constrained_value and filter the return value through #check_constraints.
-
#new_constrained ⇒ Object
Construct a new instance.
-
#process_constrained_value ⇒ Object
Filters @constrained_value through the supplied block (usually a call to #check_constraints) and collects the output in @constrained_value).
-
#respond_to?(*args) ⇒ Boolean
Forward to @constrained_value.
-
#with_constraints(new_value) ⇒ Object
Maintain object identity according to the return value of
block.
Methods included from Helper
and_constraint, handle_constraint_violation, log_constraint_exception, or_constraint
Constructor Details
#initialize(core = nil, predecessor = nil) ⇒ Shell
Returns a new instance of Shell.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/constraint.rb', line 218 def initialize(core=nil, predecessor=nil) if predecessor @descriptions = predecessor.descriptions @constraints = predecessor.constraints else @descriptions = self.class.descriptions.dup @constraints = self.class.constraints @constraints = @constraints.dup if @constraints end if core @constrained_value = core else @constrained_value = new_constrained end unless CONSTRAINT_DISABLE process_constrained_value {|e| check_constraints(e)} end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Delegate unknown methods to @constrained_value and filter the return value through #check_constraints.
See also the notes on #with_constraints and Shell.with_arguments_constrained.
313 314 315 |
# File 'lib/constraint.rb', line 313 def method_missing(method, *args, &block) with_constraints(@constrained_value.send(method, *args, &block)) end |
Instance Attribute Details
#constrained_value ⇒ Object (readonly)
The actual value that is covered by the Shell.
150 151 152 |
# File 'lib/constraint.rb', line 150 def constrained_value @constrained_value end |
Class Method Details
.inherited(subclass) ⇒ Object
158 159 160 161 162 163 |
# File 'lib/constraint.rb', line 158 def inherited(subclass) parent = self subclass.class_eval do inherit_constraint(parent) end end |
.with_all_arguments_constrained(*methods) ⇒ Object
Wrap methods so that all arguments are filtered through #check_constraints.
- methods
-
Method names as symbols
168 169 170 171 172 |
# File 'lib/constraint.rb', line 168 def with_all_arguments_constrained(*methods) with_arguments_constrained(*methods) do |checker, *args| args.collect {|e| checker.call(e)} end end |
.with_arguments_constrained(*methods, &block) ⇒ Object
Wrap methods so that some arguments are filtered through #check_constraints. This is useful in two situations:
* if filtering the return value would be inefficient --
e.g. with methods performing trivial Array operations
where the return value will comply with the constraints
if its argument do.
* if the return value of the method call is not an
instance of the actual value's class (only then will the
value's integrity be checked)
See also the notes on Shell#with_constraints.
- methods
-
Method names as symbols
- block
-
Select the arguments that should be filtered
191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/constraint.rb', line 191 def with_arguments_constrained(*methods, &block) unless CONSTRAINT_DISABLE methods.each do |method| define_method(method) do |*args| unless args.empty? checker = lambda {|a| check_constraints(a)} args = block.call(checker, *args) end with_constraints(@constrained_value.send(method, *args)) end end end end |
.without_constraints(*methods) ⇒ Object
Delegate methods to @constrained_value without taking any measures.
207 208 209 210 211 212 213 |
# File 'lib/constraint.rb', line 207 def without_constraints(*methods) methods.each do |method| define_method(method) do |*args| with_constraints(@constrained_value.send(method, *args)) end end end |
Instance Method Details
#check_constraints(object) ⇒ Object
Check if object complies with @constraints.
267 268 269 |
# File 'lib/constraint.rb', line 267 def check_constraints(object) object end |
#clone ⇒ Object
243 244 245 |
# File 'lib/constraint.rb', line 243 def clone replicate_constraint_shell(super) end |
#dup ⇒ Object
239 240 241 |
# File 'lib/constraint.rb', line 239 def dup replicate_constraint_shell(super) end |
#new_constrained ⇒ Object
Construct a new instance.
248 249 250 251 |
# File 'lib/constraint.rb', line 248 def new_constrained # nil raise 'Subclass responsibility' end |
#process_constrained_value ⇒ Object
Filters @constrained_value through the supplied block (usually a call to #check_constraints) and collects the output in @constrained_value).
- block
-
The filter
257 258 259 |
# File 'lib/constraint.rb', line 257 def process_constrained_value @constrained_value = yield @constrained_value end |
#respond_to?(*args) ⇒ Boolean
Forward to @constrained_value.
322 323 324 |
# File 'lib/constraint.rb', line 322 def respond_to?(*args) super or @constrained_value.respond_to?(*args) end |
#with_constraints(new_value) ⇒ Object
Maintain object identity according to the return value of block. This method can be used when overwriting specific methods and if you don’t want to use the provided wrapper methods (e.g., Shell.with_arguments_constrained).
If the return value is of the same kind as @constrained_value and if block can’t be trusted, then the return value is filtered through #check_constraints.
In order to filter the arguments of methods that don’t return an object of the same kind as @constrained_value, you have to define an explicit delegator using Shell.with_arguments_constrained and friends.
- new_value
-
The result from the method call
- [block]
-
Optional, called @constrained_value is
new_value
292 293 294 295 296 297 298 299 300 301 |
# File 'lib/constraint.rb', line 292 def with_constraints(new_value) if new_value.equal?(@constrained_value) yield if block_given? return self elsif new_value.instance_of?(@constrained_value.class) return self.class.new(new_value, self) else return new_value end end |