Smart Init Build Status Gem Version

Do you find yourself writing a lot of boilerplate code like that?

def initialize(network_provider, api_token)
  @network_provider = network_provider
  @api_token = api_token
end

Gem provides a simple DSL for getting rid of it. It offers an alternative to using Struct.new which does not check for number of parameters provided in initializer, exposes getters and instantiates unecessary class instances.

Smart Init offers a unified api for stateless service objects, accepting values in initializer and exposing one public class method call which instantiates new objects and accepts arguments passed to initializer.

Installation

In your Gemfile

gem 'smart_init'

Keyword arguments API

You can use it either by extending a module:

class ApiClient
  extend SmartInit

  initialize_with :network_provider, api_token: "default_token"
end

or subclassing:

class ApiClient < SmartInit::Base
  initialize_with :network_provider, api_token: "default_token"
end

Now you can just:

object = ApiClient.new(network_provider: Faraday.new, api_token: 'secret_token')
# <ApiClient:0x007fa16684ec20 @network_provider=Faraday<...>, @api_token="secret_token">

You can also use is_callable method:

class Calculator < SmartInit::Base
  initialize_with :data
  is_callable

  def call
    ...
    result
  end
end

Calculator.call(data: data) => result

Default arguments

You can use keyword based, default argument values:

class Added < SmartInit::Base
  initialize_with :num_a, num_b: 2
  is_callable

  def call
    num_a + num_b
  end
end

Adder.call(num_a: 2) => 4
Adder.call(num_a: 2, num_b: 3) => 5

Legacy API

Alternatively you can use standard API without keyword arguments:

class Calculator < SmartInit::Base
  initialize_with :data
  is_callable

  def call
    ...
    result
  end
end

Calculator.call(data) => result

It does not support default argument values though.