Class: Sinclair

Inherits:
Object
  • Object
show all
Includes:
OptionsParser
Defined in:
lib/sinclair.rb,
lib/sinclair/config.rb,
lib/sinclair/version.rb,
lib/sinclair/matchers.rb,
lib/sinclair/configurable.rb,
lib/sinclair/config_builder.rb,
lib/sinclair/config_factory.rb,
lib/sinclair/options_parser.rb,
lib/sinclair/method_definition.rb,
lib/sinclair/matchers/add_method.rb,
lib/sinclair/matchers/add_method_to.rb

Overview

Builder that add instance methods to a class

Examples:

Stand alone usage

class MyModel
end

buider = Sinclair.new(MyModel)

value = 10
builder.add_method(:default_value) { value }
builder.add_method(:value, '@value || default_value')
builder.add_method(:value=) { |val| @value = val }
builder.build

instance = MyModel.new
instance.value # returns 10
instance.value = 20
instance.value # returns 20

Author:

  • darthjee

Defined Under Namespace

Modules: Configurable, Matchers, OptionsParser Classes: Config, ConfigBuilder, ConfigFactory, MethodDefinition

Constant Summary collapse

VERSION =
'1.3.0'

Instance Attribute Summary

Attributes included from OptionsParser

#options

Instance Method Summary collapse

Methods included from OptionsParser

#options_object

Constructor Details

#initialize(klass, options = {}) ⇒ Sinclair

Returns a new instance of Sinclair

Examples:

Preparing builder


class Purchase
  def initialize(value, quantity)
    @value = value
    @quantity = quantity
  end
end

builder = Sinclair.new(Purchase)

Passing building options (Used on subclasses)


class MyBuilder < Sinclair
  def add_methods
    if options_object.rescue_error
      add_safe_method
    else
      add_method(:symbolize) { @variable.to_sym }
    end
  end

  def add_safe_method
    add_method(:symbolize) do
      begin
        @variable.to_sym
      rescue StandardError
        :default
      end
    end
  end
end

class MyModel
end

builder = MyBuilder.new(MyModel, rescue_error: true)

builder.add_method
builder.build

instance = MyModel.new

instance.symbolize # returns :default

Parameters:

  • klass (Class) —

    to receive the methods

  • options (Hash) (defaults to: {}) —

    open hash options to be used by builders inheriting from Sinclair through the Sinclair::OptionsParser concern



89
90
91
92
# File 'lib/sinclair.rb', line 89

def initialize(klass, options = {})
  @klass = klass
  @options = options
end

Instance Method Details

#add_method(name, code) ⇒ Array<MethodDefinition> #add_method(name, &block) ⇒ Array<MethodDefinition>

add a method to the method list to be created on klass

Examples:

Using string code

class Person
  attr_reader :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end
end

builder = Sinclair.new(Person)
builder.add_method(:full_name, '[first_name, last_name].join(" ")')
builder.build

Person.new('john', 'wick').full_name # returns 'john wick'

Using block

builder = Sinclair.new(Person)
builder.add_method(:bond_name) { "#{last_name}, #{full_name}" }
builder.build

Person.new('john', 'wick').bond_name # returns 'wick, john wick'

Overloads:

  • #add_method(name, code) ⇒ Array<MethodDefinition>

    Parameters:

    • name (String, Symbol) —

      name of the method to be added

    • code (String) —

      code to be evaluated when the method is ran

  • #add_method(name, &block) ⇒ Array<MethodDefinition>

    Parameters:

    • name (String, Symbol) —

      name of the method to be added

    • block (Proc) —

      block to be ran as method

Returns:



151
152
153
# File 'lib/sinclair.rb', line 151

def add_method(name, code = nil, **options, &block)
  definitions << MethodDefinition.new(name, code, **options, &block)
end

#build ⇒ Array<MethodDefinition>

builds all the methods added into the klass

Examples:

Adding a default value method


class MyModel
end

buider = Sinclair.new(MyModel)

builder.add_method(:default_value) { value }

MyModel.new.respond_to(:default_value) # returns false

builder.build

MyModel.new.respond_to(:default_value) # returns true

Returns:



112
113
114
115
116
# File 'lib/sinclair.rb', line 112

def build
  definitions.each do |definition|
    definition.build(klass)
  end
end

#eval_and_add_method(name, &block) ⇒ Array<MethodDefinition>

Evaluetes a block which will result in a String, the method code

Examples:

Building a initial value class method


module InitialValuer
  extend ActiveSupport::Concern

  class_methods do
    def initial_value_for(attribute, value)
      builder = Sinclair.new(self, initial_value: value)
      builder.eval_and_add_method(attribute) do
        "@#{attribute} ||= #{options_object.initial_value}"
      end
      builder.build
    end
  end
end

class MyClass
  include InitialValuer
  attr_writer :age
  initial_value_for :age, 20
end

object = MyClass.new
object.age # 20
object.age = 30
object.age # 30

Adding option for rescue


class Purchase
  def initialize(value, quantity)
    @value = value
    @quantity = quantity
  end
end

builder = Sinclair.new(Purchase)

builder.eval_and_add_method(:total_price) do
  code = 'self.value * self.quantity'
  code.concat ' rescue 0' if options_object.rescue_error
  code
end

builder.build

Purchase.new(2.3, 5).total_price # raises error

Using option for rescue


builder = Sinclair.new(Purchase, rescue_error: true)

builder.eval_and_add_method(:total_price) do
  code = 'self.value * self.quantity'
  code.concat ' rescue 0' if options_object.rescue_error
  code
end

builder.build

Purchase.new(2.3, 5).total_price # returns 0

class Purchase
  attr_reader :value, :quantity
end

Purchase.new(2.3, 5).total_price # returns 11.5

Returns:



225
226
227
# File 'lib/sinclair.rb', line 225

def eval_and_add_method(name, &block)
  add_method(name, instance_eval(&block))
end