Class: Ribbon

Inherits:
Object
  • Object
show all
Defined in:
lib/ribbon.rb,
lib/ribbon/gem.rb,
lib/ribbon/raw.rb,
lib/ribbon/options.rb,
lib/ribbon/core_extensions.rb,
lib/ribbon/core_extensions/hash.rb,
lib/ribbon/core_extensions/array.rb,
lib/ribbon/core_extensions/object.rb,
lib/ribbon/core_extensions/basic_object.rb,
lib/ribbon/core_extensions/object/option_scope.rb,
lib/ribbon/core_extensions/object/yield_or_eval.rb

Overview

Ribbons are essentially hashes that use method names as keys.

r = Ribbon.new
r.key = :value

If you access a property that hasn’t been set, a new ribbon will be returned. This allows you to easily work with nested structures:

r.a.b.c = 10

You can also assign properties by passing an argument to the method:

r.a.b.c 20

If you pass a block, the value will be yielded:

r.a do |a|
  a.b do |b|
    b.c 30
  end
end

If the block passed takes no arguments, it will be instance_evaluated in the context of the value instead:

r.a do
  b do
    c 40
  end
end

Appending a bang (!) to the end of the property sets the value and returns the receiver:

Ribbon.new.x!(10).y!(20).z!(30)
 => {x: 10, y: 20, z: 30}

Appending a question mark (?) to the end of the property returns the contents of the property without creating a new ribbon if it is missing:

r.unknown_property?
 => nil

You can use any object as key with the [] and []= operators:

r['/some/path'].entries = []

See Also:

Author:

  • Matheus Afonso Martins Moreira

Since:

  • 0.1.0

Defined Under Namespace

Modules: CoreExtensions Classes: Gem, Options, Raw

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_values = Ribbon::Raw.new, &block) ⇒ Ribbon

Initializes a new ribbon with the given values.

If given a block, the ribbon will be yielded to it. If the block doesn’t take any arguments, it will be evaluated in the context of the ribbon.

Parameters:

See Also:

Since:

  • 0.1.0



86
87
88
89
# File 'lib/ribbon.rb', line 86

def initialize(initial_values = Ribbon::Raw.new, &block)
  self.raw = initial_values
  __yield_or_eval__ &block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

Forwards the method, arguments and block to the raw ribbon’s hash, if it responds to the method, or to the raw ribbon itself otherwise.

Since:

  • 0.1.0



101
102
103
104
# File 'lib/ribbon.rb', line 101

def method_missing(method, *arguments, &block)
  if (hash = internal_hash).respond_to? method then hash
  else raw end.__send__ method, *arguments, &block
end

Class Method Details

.compatible?(object) ⇒ true, false

Whether the object is compatible with methods that take hashes or ribbons as arguments.

Parameters:

  • object

    the object to be tested

Returns:

  • (true, false)

    whether the object is a raw ribbon

Since:

  • 0.8.0



202
203
204
# File 'lib/ribbon.rb', line 202

def compatible?(object)
  [Ribbon, Ribbon::Raw, Hash].any? { |type| type === object }
end

.deep_merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon

Merges everything inside the given ribbons.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from old_ribbon

  • new_value

    the value from new_ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (Ribbon)

    a new ribbon containing the results of the merge

See Also:

Since:

  • 0.8.0



293
294
295
# File 'lib/ribbon.rb', line 293

def deep_merge(old_ribbon, new_ribbon, &block)
  deep :merge, old_ribbon, new_ribbon, &block
end

.deep_merge!(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon, ...

Merges everything inside the given ribbons in place.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from old_ribbon

  • new_value

    the value from new_ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (Ribbon, Ribbon::Raw, Hash)

    old_ribbon, which will contain the results of the merge

See Also:

Since:

  • 0.8.0



311
312
313
# File 'lib/ribbon.rb', line 311

def deep_merge!(old_ribbon, new_ribbon, &block)
  deep :merge!, old_ribbon, new_ribbon, &block
end

.extract_hash_from(object) ⇒ Hash

Extracts the hash of a ribbon. Will attempt to convert other objects.

Parameters:

Returns:

  • (Hash)

    the resulting hash

Since:

  • 0.2.1



211
212
213
214
215
216
# File 'lib/ribbon.rb', line 211

def extract_hash_from(object)
  case object
    when Ribbon, Ribbon::Raw then object.__hash__
    else object.to_hash
  end
end

.extract_raw_from(object) ⇒ Ribbon::Raw

Extracts a raw ribbon from the given object.

Parameters:

Returns:

Since:

  • 0.8.0



223
224
225
226
227
228
229
# File 'lib/ribbon.rb', line 223

def extract_raw_from(object)
  case object
    when Ribbon then object.raw
    when Ribbon::Raw then object
    else Ribbon::Raw.new object.to_hash
  end
end

.from_yaml(string) ⇒ Ribbon

Deserializes the hash from the string using YAML and uses it to construct a new ribbon.

Parameters:

  • string (String)

    a valid YAML string

Returns:

Since:

  • 0.4.7



237
238
239
# File 'lib/ribbon.rb', line 237

def from_yaml(string)
  Ribbon.new YAML.load(string)
end

.merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon

Merges the hashes of the given ribbons.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from old_ribbon

  • new_value

    the value from new_ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (Ribbon)

    a new ribbon containing the results of the merge

See Also:

Since:

  • 0.8.0



253
254
255
256
257
258
# File 'lib/ribbon.rb', line 253

def merge(old_ribbon, new_ribbon, &block)
  old_hash = extract_hash_from old_ribbon
  new_hash = extract_hash_from new_ribbon
  merged_hash = old_hash.merge new_hash, &block
  Ribbon.new merged_hash
end

.merge!(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon, ...

Merges the hashes of the given ribbons in place.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from old_ribbon

  • new_value

    the value from new_ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (Ribbon, Ribbon::Raw, Hash)

    old_ribbon, which will contain the results of the merge

See Also:

Since:

  • 0.8.0



273
274
275
276
277
278
# File 'lib/ribbon.rb', line 273

def merge!(old_ribbon, new_ribbon, &block)
  old_hash = extract_hash_from old_ribbon
  new_hash = extract_hash_from new_ribbon
  old_hash.merge! new_hash, &block
  old_ribbon
end

.raw?(object) ⇒ true, false

Whether the given object is a raw ribbon.

Parameters:

  • object

    the object to be tested

Returns:

  • (true, false)

    whether the object is a raw ribbon

Since:

  • 0.8.0



192
193
194
# File 'lib/ribbon.rb', line 192

def raw?(object)
  Ribbon::Raw === object
end

Instance Method Details

#deep_merge(ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon

Merges everything inside this ribbon with everything inside the given ribbon, creating a new instance in the process.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from this ribbon

  • new_value

    the value from the given ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (Ribbon)

    a new ribbon containing the results of the deep merge

See Also:

Since:

  • 0.8.0



118
119
120
# File 'lib/ribbon.rb', line 118

def deep_merge(ribbon, &block)
  Ribbon.new Ribbon.deep_merge(self, ribbon, &block)
end

#deep_merge!(ribbon) {|key, old_value, new_value| ... } ⇒ self

Merges everything inside this ribbon with the given ribbon in place.

Parameters:

Yield Parameters:

  • key

    the key which identifies both values

  • old_value

    the value from this ribbon

  • new_value

    the value from the given ribbon

Yield Returns:

  • the object that will be used as the new value

Returns:

  • (self)

    this ribbon

See Also:

Since:

  • 0.8.0



133
134
135
# File 'lib/ribbon.rb', line 133

def deep_merge!(ribbon, &block)
  Ribbon.deep_merge! self, ribbon, &block
end

#internal_hashHash

The hash used by the raw ribbon.

Returns:

  • (Hash)

    the internal hash of the raw ribbon

Since:

  • 0.8.0



95
96
97
# File 'lib/ribbon.rb', line 95

def internal_hash
  raw.__hash__
end

#rawRibbon::Raw

The raw ribbon.

Returns:

Since:

  • 0.8.0



65
66
67
# File 'lib/ribbon.rb', line 65

def raw
  @raw ||= Ribbon::Raw.new
end

#raw=(object) ⇒ Ribbon::Raw

Sets this ribbon’s raw ribbon.

Parameters:

Returns:

Since:

  • 0.8.0



74
75
76
# File 'lib/ribbon.rb', line 74

def raw=(object)
  @raw = Ribbon.extract_raw_from object
end

#to_hashHash

Converts this ribbon and all ribbons inside into hashes.

Returns:

  • (Hash)

    the converted contents of this wrapped ribbon

Since:

  • 0.8.0



141
142
143
# File 'lib/ribbon.rb', line 141

def to_hash
  to_hash_recursive
end

#to_s(*arguments, &block) ⇒ String Also known as: inspect

Delegates to the raw ribbon.

Returns:

  • (String)

    the string representation of this ribbon

See Also:

Since:

  • 0.1.0



158
159
160
# File 'lib/ribbon.rb', line 158

def to_s(*arguments, &block)
  raw.to_s *arguments, &block
end

#to_yamlString

Converts this ribbon to a hash and serializes it with YAML.

Returns:

  • (String)

    the YAML string that represents this ribbon

See Also:

Since:

  • 0.8.0



150
151
152
# File 'lib/ribbon.rb', line 150

def to_yaml
  to_hash.to_yaml
end