Module: ConfigLeaf

Defined in:
lib/config_leaf.rb,
lib/config_leaf/version.rb,
lib/config_leaf/wrapper.rb

Defined Under Namespace

Classes: Wrapper

Constant Summary collapse

VERSION =
"0.0.2"

Class Method Summary collapse

Class Method Details

.wrap(object, &block) ⇒ Object

Wraps an object and redirects public methods to it, to allow for a terse, block-based API.

  • Safer alternative to running Object#instance_eval directly, since protected/private methods and instance variables are not exposed.

  • Less wordy than a system which operates like Object#tap (‘object.tap {|o| o.fish = 5; o.run }`)

A method call, #meth called on the wrapper will try to call #meth or #meth= on the owner, as appropriate.

# User chooses to not use ConfigLeaf block syntax by requesting a block parameter.
object2 = Cheese.new do |c|
   c.list = [1, 2, 3]
   c.list << 4
   c.value = 5
   c.value = c.list.size
   c.invert
 end

Examples:

Using ConfigLeaf to configure an object externally.

# To create a DSL block for a given object.
class Cheese
  attr_accessor :value, :list

  def initialize
    @value = 0
    @list = []
  end

  def invert
    @list.reverse!
  end
end

object = Cheese.new
ConfigLeaf.wrap object do
  list [1, 2, 3]      # Calls object.list = [1, 2, 3]
  list << 4           # Calls object.list << 4
  value 5             # Calls object.value = 5
  value list.size     # Calls object.value = object.list.size
  invert              # Calls object.invert
end

Allowing the user to configure the object externally.

# To create a DSL block for a given object.
class Cheese
  attr_accessor :value, :list

  def initialize(&block)
    @value = 0
    @list = []

    ConfigLeaf.wrap self, &block if block_given?
  end

  def invert
    @list.reverse!
  end
end

# User chooses to use the ConfigLeaf block syntax.
object1 = Cheese.new do
  list [1, 2, 3]      # Calls object.list = [1, 2, 3]
  list << 4           # Calls object.list << 4
  value 5             # Calls object.value = 5
  value list.size     # Calls object.value = object.list.size
  invert              # Calls object.invert
end

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
# File 'lib/config_leaf.rb', line 72

def wrap(object, &block)
  raise ArgumentError, "block is required" unless block_given?

  if block.arity == 0 # e.g. { }
    Wrapper.wrap object, &block
  else                # e.g. {|me| }
    block.call object
  end
end