Class: Marble

Inherits:
Object
  • Object
show all
Defined in:
lib/marble.rb,
lib/marble/version.rb,
lib/marble/rails_template_handler.rb

Overview

Builder for Ruby objects. Provides a convenient interface for generating complex arrays and hashes.

First instantiate a builder:

builder = Marble.new

Then, call either #build, #array, or #hash on the builder. You can use the yielded block parameter to give the builder a shorter name. I suggest m.

builder.hash do |m|
  m.zombies 'oh my!'
end

The returned value is the built object.

Defined Under Namespace

Classes: RailsTemplateHandler

Constant Summary collapse

VERSION =

Marble version number

'0.1.0'

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

Calls #pair or #key depending on the context.

When the current structure responds to #push (for example, in an array context), it calls #item ignoring the method name. This allows you to be more semantic when defining the items in an array. However, in most cases calling #item will suffice.

When the current structure responds to #[]= (for example, in a hash context), it calls #pair with the stringified method name as the key. This, in general, is a more concise and preferred way than explicitly calling #pair.

Examples:

Build an array

builder = Marble.new
builder.array do |m|
  m.milk 'toast'
end # => ['foo', 'bar']

Build a hash

builder = Marble.new
builder.hash do |m|
  m.milk 'toast'
end # => { 'milk' => 'toast' }


111
112
113
114
115
116
117
118
119
# File 'lib/marble.rb', line 111

def method_missing(method, *args, &block)
  if @current.respond_to?(:push)
    item(*args, &block)
  elsif @current.respond_to?(:[]=)
    pair(method.to_s, *args, &block)
  else
    super
  end
end

Instance Method Details

#array {|builder| ... } ⇒ Array

Builds an array.

Examples:

Build a simple array

builder = Marble.new
builder.array do |m|
  m.item 'foo'
  m.item 'bar'
end # => ['foo', 'bar']

Build nested arrays

builder = Marble.new
builder.array do |m|
  m.item :array do
    m.item 'foo'
  end
end # => [['foo']]

Yields:

  • (builder)

    block to evaluate within the array's context

Yield Parameters:

  • builder (Marble)

    the current builder

Returns:

  • (Array)

    the built array



84
85
86
# File 'lib/marble.rb', line 84

def array(&block)
  insert_structure([], &block)
end

#build {|builder| ... } ⇒ Object

Builds an arbitrary value.

Examples:

Build a simple value

builder = Marble.new
builder.build do |m|
  true
end # => true

Build a more complex value

builder = Marble.new
builder.build do |m|
  m.array do
    m.item 'foo'
  end
end # => ['foo']

Yields:

  • (builder)

    block to evaluate for the value

Yield Parameters:

  • builder (Marble)

    the current builder

Returns:

  • (Object)

    the built value



36
37
38
# File 'lib/marble.rb', line 36

def build(&block)
  value_structure(&block)
end

#hash {|builder| ... } ⇒ Hash

Builds a hash.

Examples:

Build a simple hash

builder = Marble.new
builder.hash do |m|
  m.foo 'bar'
  m.baz 'quz'
end # => { 'foo' => 'bar', 'baz' => 'quz' }

Build nested hashes

builder = Marble.new
builder.hash do |m|
  m.foo :hash do
    m.bar 'baz'
  end
end # => { 'foo' => { 'bar' => 'baz' } }

Yields:

  • (builder)

    block to evaluate within the hash's context

Yield Parameters:

  • builder (Marble)

    the current builder

Returns:

  • (Hash)

    the built hash



60
61
62
# File 'lib/marble.rb', line 60

def hash(&block)
  insert_structure({}, &block)
end

#item(value) ⇒ Object #item {|builder| ... } ⇒ Object #item(structure_type) {|builder| ... } ⇒ Object

Inserts an item into the current structure.

Arrays are the most common structure into which you insert an item (any value). Items are inserted using #push, so if you'd like to duck-type an array for whatever reason, go ahead.

You can provide values using either the second parameter or a block. If you provide a block, the block will be evaluated immediately.

Blocks by default insert the value of the block into the item. However, you can optionally specify the structure type of the block as either :array or :hash to insert an array or hash structure. That means that these are all equivalent:

m.array do
  m.item ['value']
end

m.array do
  m.item do
    ['value']
  end
end

m.array do
  m.item :hash do
    m.pair 'key', 'value'
  end
end

Choose the format that makes the most sense in a given context.

Overloads:

  • #item(value) ⇒ Object

    Parameters:

    • value (Object)

      the value to insert into the item

  • #item {|builder| ... } ⇒ Object

    Yields:

    • (builder)

      block to evaluate for the item's value

    Yield Parameters:

    • builder (Marble)

      the current builder

    Yield Returns:

    • (Object)

      the value to insert into the item

  • #item(structure_type) {|builder| ... } ⇒ Object

    Parameters:

    • structure_type (:array, :hash)

      the block's structure type

    Yields:

    • (builder)

      block to evaluate for the item's value

    Yield Parameters:

    • builder (Marble)

      the current builder

    Yield Returns:

    • (Object)

      the value to insert into the item



164
165
166
167
168
169
170
# File 'lib/marble.rb', line 164

def item(value_or_structure_type = nil, &block)
  if block_given?
    @current.push evaluate_structure(value_or_structure_type, &block)
  else
    @current.push value_or_structure_type
  end
end

#pair(key, value) ⇒ Object #pair(key) {|builder| ... } ⇒ Object #pair(key, structure_type) {|builder| ... } ⇒ Object

Inserts a pair into the current structure.

Hashes are the most common structure into which you insert a pair (key and value). Pairs are inserted using #[]=, so if you'd like to duck-type a hash for whatever reason, go ahead.

You can provide values using either the second parameter or a block. If you provide a block, the block will be evaluated immediately.

Blocks by default insert the value of the block into the pair. However, you can optionally specify the structure type of the block as either :array or :hash to insert an array or hash structure. That means that these are all equivalent:

m.hash do
  m.pair 'key', ['value']
end

m.hash do
  m.pair 'key' do
    ['value']
  end
end

m.hash do
  m.pair 'key', :array do
    m.item 'value'
  end
end

Choose the format that makes the most sense in a given context.

Overloads:

  • #pair(key, value) ⇒ Object

    Parameters:

    • key (Object)

      the key to use for the pair

    • value (Object)

      the value to insert into the pair

  • #pair(key) {|builder| ... } ⇒ Object

    Parameters:

    • key (Object)

      the key to use for the pair

    Yields:

    • (builder)

      block to evaluate for the pair's value

    Yield Parameters:

    • builder (Marble)

      the current builder

    Yield Returns:

    • (Object)

      the value to insert into the pair

  • #pair(key, structure_type) {|builder| ... } ⇒ Object

    Parameters:

    • key (Object)

      the key to use for the pair

    • structure_type (:array, :hash)

      the block's structure type

    Yields:

    • (builder)

      block to evaluate for the pair's value

    Yield Parameters:

    • builder (Marble)

      the current builder

    Yield Returns:

    • (Object)

      the value to insert into the pair



218
219
220
221
222
223
224
# File 'lib/marble.rb', line 218

def pair(key, value_or_structure_type = nil, &block)
  if block_given?
    @current[key] = evaluate_structure(value_or_structure_type, &block)
  else
    @current[key] = value_or_structure_type
  end
end