WrapperBased
Wrapper Based DCI framework for OOP done right.
Installation
Add this line to your application's Gemfile:
gem 'wrapper_based'
And then execute:
$ bundle
Usage
Dijkstra data | Dijkstra test | Djikstra example:
module DestinationNode
def shortest_path_from(neighbor, find_shortest)
return [self] if equal? neighbor
find_shortest.path(from: neighbor)
end
end
Map = DCI::Module.new do |mod| using mod
def distance_between(a, b)
@distances[Edge.new(a, b)]
end
def distance_of(path)
path.each_cons(2).inject(0) { |total, (to, from)| total + distance_between(from, to) }
end
def neighbors(near:)
[south_neighbor_of(near), east_neighbor_of(near)].compact # excludes nil neighbors
end
end
class FindShortest < DCI::Context(:from, to: DestinationNode, city: Map)
def initialize(city:, from: city.root, to: city.destination) super end
def distance
city.distance_of path
end
def path(from: @from)
shortest_neighbor_path(from) << from
end
private
def shortest_neighbor_path(current)
city.neighbors(near: current).
map { |neighbor| to.shortest_path_from(neighbor, self) }.
min_by { |neighbor_path| city.distance_of neighbor_path }
end
end
Context methods
context#to_proc
Returns call method as a Proc.
['Card Wars', 'Ice Ninja Manual', 'Bacon'].map &GiftToy[gifter: 'Jake', giftee: 'Finn']
context[params,...]
Square brackets are alias for call method.
TransferMoney[from: source_account, to: destination_account][amount: 100]
context#rebind(**params)
Assigns object to role.
add_member = Evaluate.new(to: 'Justice League')
['Batman', Superman', 'Wonder Woman'].each do |founder|
add_member.rebind(member: founder).(recruit: 'Supergirl')
end
Context class methods
klass#call(**params)
A shortcut for instantiating the context by passing the collaborators and then executing the context call method.
Funds::TransferMoney.(from: @account1, to: @account2, amount: 50)
Which is equivalent to:
Funds::TransferMoney.new(from: @account1, to: @account2, amount: 50).call
DCI::Module
Extention module for supporting procedural code. Define a block with the 'new' method and pass the 'mod' parameter to 'using' keyword.
AwesomeSinging = TypeWrapper::Module.new do |mod| using mod
def sing
"#{name} sings #{song}"
end
def song
"Everything is AWESOME!!!"
end
end
Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/RichOrElse/wrapper-based.
License
The gem is available as open source under the terms of the MIT License.