• Jump To … +
    db_adapters.cr state_machine.cr value_object.cr visitor.cr db_adapters.rb log_decorator.rb validation.rb value_object.rb visitor.rb
  • value_object.rb

  • ¶

    The whole idea of this is to have barebones “value object factory” that creates new classes for the given attribute names.

  • ¶

    This method will be invoked for a class object. For example, let’s say a Money class. It’ll add an initialize for the class with the given arguments as parameters, and it’ll set the instance variable with the same name for each attribute.

    def vo_initialize(attributes)
      define_method("initialize") do |values|
        attributes.zip(values).each do |attribute, value|
          instance_variable_set("@#{attribute}", value)
        end
      end
    end
  • ¶

    This other method will add reader methods that return the value of each attribute

    def vo_readers(attributes)
      attributes.each do |attribute|
        define_method(attribute) do
          instance_variable_get("@#{attribute}")
        end
      end
    end
  • ¶

    Finally we have the factory, this returns a new instance of Class (so, a class!). When we pass a block to Class.new, it gets executed in the context of the newly created class

    def value_object(*attributes)
      Class.new do
        vo_initialize(attributes)
        vo_readers(attributes)
      end
    end
  • ¶

    Tada!

    Money = value_object("currency", "amount")