Skip to content

Anatomy of some Ruby code

markmc edited this page Dec 1, 2010 · 1 revision

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?

Clone this wiki locally