-
Notifications
You must be signed in to change notification settings - Fork 0
Anatomy of some Ruby code
Ruby developers, turn away - you know this already
Other folks, take a look a this piece of code in base_driver.rb
:
module Deltacloud
class BaseDriver
def self.define_hardware_profile(...)
feature :instances, :hardware_profiles do
decl.operation(:create) { add_params(hw_params) }
end
....
The feature
method is defined in features.rb
:
module Deltacloud
class BaseDriver
def self.declare_feature(collection, name, &block)
...
decl = ...
...
features[collection] << Feature.new(decl, &block)
end
Okay, so the call to the feature
method passes the collection symbol, the feature name symbol and a code block (between do
and end
). The code block is passed to the Feature
initializer:
class Feature
attr_reader :decl
def initialize(decl, &block)
@decl = decl
instance_eval &block
end
Using instance_eval
, the block is evaluated in the context of this Feature
instance. As you can see in the first snippet, the block references the decl
property:
decl.operation(:create) { add_params(hw_params) }
The FeatureDecl.operation
method looks like:
class FeatureDecl
def operation(name, &block)
...
op.instance_eval(&block)
...
So, the operation
method is called with the :create
operation name symbol and a block (this time between {
and }
). This block is evaluated in the context of the Operation
instance and calls the add_params
method. But wait, where is that method defined?
class Operation
include Deltacloud::Validation
Yes, it's defined in the Validation
class in validation.rb
:
def add_params(new)
new.each { |p| @params[p.name] = p }
end
My, my - how's that for twistiness?