Class: Ribbon
- Inherits:
- BasicObject
- Defined in:
- lib/ribbon.rb,
lib/ribbon/gem.rb,
lib/ribbon/options.rb,
lib/ribbon/wrapper.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_eval
uated 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 = []
Defined Under Namespace
Modules: CoreExtensions Classes: Gem, Options, Wrapper
Class Method Summary collapse
-
.convert(object) ⇒ Object
Converts hashes to ribbons.
-
.convert_all!(ribbon) ⇒ Ribbon, Ribbon::Wrapper
Converts all values inside the given ribbon.
-
.deep_merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon
Merges everything inside the given ribbons.
-
.deep_merge!(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon, ...
Merges everything inside the given ribbons in place.
-
.default_value_proc ⇒ Proc
Proc used to store a new Ribbon instance as the value of a missing key.
-
.extract_hash_from(parameter) ⇒ Hash
Returns the hash of a Ribbon.
-
.from_yaml(string) ⇒ Ribbon
Deserializes the hash from the string using YAML and uses it to construct a new ribbon.
-
.instance?(object) ⇒ true, false
Tests whether the given object is an instance of Ribbon.
-
.merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon
Merges the hashes of the given ribbons.
-
.merge!(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon, ...
Merges the hashes of the given ribbons in place.
-
.wrap(object = ::Ribbon.new, &block) ⇒ Ribbon::Wrapper
Wraps an object in a Wrapper.
-
.wrapped?(ribbon) ⇒ true, false
Tests whether the given object is an instance of Wrapper.
Instance Method Summary collapse
-
#[](key, &block) ⇒ Object
Fetches the value associated with the given key.
-
#[]=(key, *values) ⇒ Object
Associates the given values with the given key.
-
#__hash__ ⇒ Hash
private
The hash used internally.
-
#initialize(hash = {}, &block) ⇒ Ribbon
constructor
Initializes a new ribbon.
-
#method_missing(method, *args, &block) ⇒ Object
Handles the following cases:.
-
#to_s(opts = {}) ⇒ String
(also: #inspect)
Generates a simple
key: value
string representation of this ribbon.
Constructor Details
#initialize(hash = {}, &block) ⇒ Ribbon
Initializes a new ribbon.
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.
All objects inside the hash will be converted.
81 82 83 84 85 |
# File 'lib/ribbon.rb', line 81 def initialize(hash = {}, &block) __hash__.merge! ::Ribbon.extract_hash_from(hash) __yield_or_eval__ &block ::Ribbon.convert_all! self end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Handles the following cases:
ribbon.method => ribbon[method]
ribbon.method value => ribbon[method] = value
ribbon.method &block => ribbon[method, &block]
ribbon.method value, &block => ribbon[method] = value
ribbon[method, &block]
ribbon.method = value => ribbon[method] = value
ribbon.method! value => ribbon[method] = value
self
ribbon.method! &block => ribbon[method, &block]
self
ribbon.method! value, &block => ribbon[method] = value
ribbon[method, &block]
self
ribbon.method? => ribbon.__hash__.fetch method
ribbon.method? value => ribbon.__hash__.fetch method, value
ribbon.method? &block => ribbon.__hash__.fetch method, &block
ribbon.method? value, &block => ribbon.__hash__.fetch method, value, &block
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/ribbon.rb', line 141 def method_missing(method, *args, &block) method_string = method.to_s key = method_string.strip.gsub(/[=?!]$/, '').strip.intern case method_string[-1] when ?= __send__ :[]=, key, *args when ?! __send__ :[]=, key, *args unless args.empty? self[key, &block] self when ?? begin self.__hash__.fetch key, *args, &block rescue ::KeyError; nil end else __send__ :[]=, key, *args unless args.empty? self[key, &block] end end |
Class Method Details
.convert(object) ⇒ Object
Converts hashes to ribbons. Will look inside arrays.
216 217 218 219 220 221 222 |
# File 'lib/ribbon.rb', line 216 def convert(object) case object when Hash then Ribbon.new object when Array then object.map { |element| convert element } else object end end |
.convert_all!(ribbon) ⇒ Ribbon, Ribbon::Wrapper
Converts all values inside the given ribbon.
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/ribbon.rb', line 231 def convert_all!(ribbon) ribbon.__hash__.each do |key, value| ribbon[key] = case value when Ribbon then convert_all! value when Ribbon::Wrapper then convert_all! value.ribbon else convert value end end ribbon end |
.deep_merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon
Merges everything inside the given ribbons.
300 301 302 |
# File 'lib/ribbon.rb', line 300 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.
320 321 322 |
# File 'lib/ribbon.rb', line 320 def deep_merge!(old_ribbon, new_ribbon, &block) deep :merge!, old_ribbon, new_ribbon, &block end |
.default_value_proc ⇒ Proc
Proc used to store a new Ribbon instance as the value of a missing key.
207 208 209 |
# File 'lib/ribbon.rb', line 207 def default_value_proc @default_value_proc ||= (proc { |hash, key| hash[key] = Ribbon.new }) end |
.extract_hash_from(parameter) ⇒ Hash
Returns the hash of a Ribbon. Will attempt to convert other objects.
356 357 358 359 360 361 362 |
# File 'lib/ribbon.rb', line 356 def extract_hash_from(parameter) case parameter when Ribbon::Wrapper then parameter.internal_hash when Ribbon then parameter.__hash__ else parameter.to_hash end end |
.from_yaml(string) ⇒ Ribbon
Deserializes the hash from the string using YAML and uses it to construct a new ribbon.
370 371 372 |
# File 'lib/ribbon.rb', line 370 def from_yaml(string) Ribbon.new YAML.load(string) end |
.instance?(object) ⇒ true, false
Tests whether the given object is an instance of Ribbon.
329 330 331 |
# File 'lib/ribbon.rb', line 329 def instance?(object) Ribbon === object end |
.merge(old_ribbon, new_ribbon) {|key, old_value, new_value| ... } ⇒ Ribbon
Merges the hashes of the given ribbons.
256 257 258 259 260 261 |
# File 'lib/ribbon.rb', line 256 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.
278 279 280 281 282 283 |
# File 'lib/ribbon.rb', line 278 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 |
Instance Method Details
#[](key, &block) ⇒ Object
Fetches the value associated with the given key.
If given a block, the value will be yielded to it. If the block doesn’t take any arguments, it will be evaluated in the context of the value.
95 96 97 98 99 |
# File 'lib/ribbon.rb', line 95 def [](key, &block) value = ::Ribbon.convert __hash__[key] value.__yield_or_eval__ &block self[key] = value end |
#[]=(key, *values) ⇒ Object
Associates the given values with the given key.
115 116 117 |
# File 'lib/ribbon.rb', line 115 def []=(key, *values) __hash__[key] = if values.size == 1 then values.first else values end end |
#__hash__ ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The hash used internally.
66 67 68 |
# File 'lib/ribbon.rb', line 66 def __hash__ @hash ||= (::Hash.new &::Ribbon.default_value_proc) end |
#to_s(opts = {}) ⇒ String Also known as: inspect
Generates a simple key: value
string representation of this ribbon.
170 171 172 |
# File 'lib/ribbon.rb', line 170 def to_s(opts = {}) __to_s_recursive__ ::Ribbon.extract_hash_from(opts) end |