Module: Kernel
- Defined in:
- lib/contract/integration.rb
Instance Method Summary collapse
-
#adaption(options = {}, &block) ⇒ Object
Adds an adaption route from the specified type to the specified type.
Instance Method Details
#adaption(options = {}, &block) ⇒ Object
Adds an adaption route from the specified type to the specified type. Basic usage looks like this:
adaption :from => StringIO, :to => String, :via => :read
This method takes various options. Here’s a complete list:
:from
-
The type that can be converted from. Defaults to
self
meaning you can safely omit it in Class, Module or Contract context. :to
-
The type that can be converted to. Defaults to
self
meaning you can safely omit it in Class, Module or Contract context.Note that you need to specify either
:from
or:to
. :via
-
How the
:from
type will be converted to the:to
type. If this is a Symbol the conversion will be done by invoking the method identified by that Symbol on the source object. Otherwise this should be something that responds to thecall
method (for example Methods and Procs) which will get the source object as its argument and which should return the target object. :if
-
The conversion can only be performed if this condition is met. This can either be something that implements the === case equivalence operator or something that implements the
call
method. So Methods, Procs, Modules, Classes and Contracts all make sense in this context. You can also specify a Symbol in which case the conversion can only be performed if the source object responds to the method identified by that Symbol.Note that the
:if
option will default to the same value as the:via
option if the:via
option is a Symbol.
If you invoke this method with a block it will be used instead of the :via
option.
See Contract.adapt for how conversion look-ups are performed.
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
# File 'lib/contract/integration.rb', line 512 def adaption( = {}, &block) # :yield: source_object = { :from => self, :to => self }.merge() if block then if .include?(:via) then raise(ArgumentError, "Can't use both block and :via") else [:via] = block end end if [:via].respond_to?(:to_sym) then [:via] = [:via].to_sym end [:if] ||= [:via] if [:via].is_a?(Symbol) if [:via].is_a?(Symbol) then symbol = [:via] [:via] = lambda { |obj| obj.send(symbol) } end if [:if].respond_to?(:to_sym) then [:if] = [:if].to_sym end if [:if].is_a?(Symbol) then [:if] = Contract::Check::Quack[[:if]] elsif [:if].respond_to?(:call) then callable = [:if] [:if] = Contract::Check.block { |obj| callable.call(obj) } end if [:from] == self and [:to] == self then raise(ArgumentError, "Need to specify either :from or :to") elsif [:from] == [:to] then raise(ArgumentError, "Self-adaption: :from and :to both are " + [:to].inspect) end unless [:via] raise(ArgumentError, "Need to specify how to adapt (use :via or block)") end Contract.adaptions[[:to]] << end |