ccp
CCP is a Ruby library for Composite Command Programming that helps you to split spaghetti codes into pieces.
Websites
What is a Composite Command Programming?
There are three principles.
-
SRP (Single responsibility principle)
-
Typed Variables (especially needed in Ruby)
-
Explicit Data Dependencies
As you know, Ruby is a handy and powerful programming language. We can use variables without definitions and re-assign them even if type mismatch. Although it is very comfortable while you are writing, it would be painful for others.
CCP is a framework composed with above principles and a few debugging utils that gives you(as writer) a little restrictions and gives you(as reader) a readability.
Example
usual ruby code
class SomeOperation
def execute
# fetching data
# calculating it
# print results
end
end
Later, it would be a more complex and longer code like this.
class SomeOperation
def execute
@data = fetch_data
...
@result = calculate(@data)
...
print_results(@result)
end
def fetching_data
# accessing instance variables, and long code here
...
Let’s imagine a situation that you need to replace above “fetch” code after several years. It is too hard to see data dependencies especially about instance variables.
with CCP
class SomeOperation
include Ccp::Commands::Composite
command FetchData
command Calculate
command PrintResult
end
class FetchData # 1. SRP
include Ccp::Commands::Core
# {before,after} methods can be used like Design By Contract
def after
data.check(:fetched, {Symbol => [Float]}) # 2. Typed Variables
end
def execute
# fetching data...
data[:fetched] = ... # 3. Data Dependencies
end
end
class Calculate
...
All sub commands like FetchData,Calculate,PrintResult are executed in each scopes, and can share variables only via data object.
So you can easily refactor or replace FetchData unit because there are no implicit instance variable dependencies and futhermore all depencenies would be explicitly declared in “before”,“after” method.
execute
Just call a “execute” instance method.
cmd = SomeOperation.new
cmd.execute
invokers
Invokers::Base can be used as a top level composite command.
class SomeOperation < Ccp::Invokers::Base
command FetchData
...
Its “benchmark” method generates profile information.
ruby -r some_operation -e 'SomeOperation.new.benchmark'
[43.3%] 2.5834830 FetchData#execute
[35.9%] 2.0710440 Calculate#execute
...