Class: Octothorpe
Overview
A very simple hash-like class that borrows a little from OpenStruct, etc.
-
Treats string and symbol keys as equal
-
Access member objects with ot.>>.keyname
-
Guard conditions allow you to control what returns if key is not present
-
Pretty much read-only, for better or worse
Meant to facilitate message-passing between classes.
Simple example:
ot = Octothorpe.new(one: 1, "two" => 2, "weird key" => 3)
ot.>>.one # -> 1
ot.>>.two # -> 2
ot.get("weird key") # -> 3
With guard conditions:
ot = Octotghorpe.new(one: 1, "two" => 2)
ot.guard(Array, :three)
ot.freeze # optional step - makes OT truly read-only
ot.>>.three # -> []
ot.>>.three[9] # valid (of course; returns nil)
Octothorpe additionally responds to the following methods exactly as a Hash would:
empty?, has_key?, has_value?, include?
each, each_key, each_value, keys, values
select, map, reject, inject
merge, <, >< ==, >+, <=
Defined Under Namespace
Classes: BadHash, Frozen, OctoError, Storage
Constant Summary collapse
- VERSION =
Gem version number
'0.4.1'
Instance Method Summary collapse
- #<(other) ⇒ Object
- #<=(other) ⇒ Object
-
#==(other) ⇒ Object
Resolve some of the standard comparisons (with an OT or a hash).
- #>(other) ⇒ Object
- #>=(other) ⇒ Object
-
#>> ⇒ Object
:call-seq: ot.>>.keyname.
-
#get(key) ⇒ Object
(also: #send, #[])
:call-seq: ot.get(key) ot.send(key) ot.
-
#guard(*args) ⇒ Object
:call-seq: ot.guard( class, key [, key, …] ) ot.guard( key, [,key, …] ) {|k| … }.
-
#initialize(hash = nil) ⇒ Octothorpe
constructor
:call-seq: ot = Octothrpe.new(hash).
-
#inspect ⇒ Object
Inspect exposes a view of the inner hash.
-
#merge(other) ⇒ Object
:call-seq: ot.merge(other) -> new_ot ot.merge(other){|key, oldval, newval| block} -> new_ot.
-
#to_h ⇒ Object
Returns a hash of the object.
-
#whitelist(*keys) ⇒ Object
:call-seq: ot.whitelist(:one, :two, :three) -> new_ot.
Constructor Details
#initialize(hash = nil) ⇒ Octothorpe
:call-seq:
ot = Octothrpe.new(hash)
Initialise an Octothorpe object by passing it a hash.
You can create an empty OT by calling Octothorpe.new, but there’s probably little utility in that, given that it is read-only.
If you pass anything other than nil or something OT can treat as a Hash, you will cause an Octothorpe::BadHash exception.
89 90 91 92 |
# File 'lib/octothorpe.rb', line 89 def initialize(hash=nil) @store = Storage.new( symbol_hash(hash || {}) ) @inner_hash = @store.octothorpe_store end |
Instance Method Details
#<(other) ⇒ Object
208 |
# File 'lib/octothorpe.rb', line 208 def <(other); compare_as_hash(other, :<); end |
#<=(other) ⇒ Object
211 |
# File 'lib/octothorpe.rb', line 211 def <=(other); compare_as_hash(other, :<=); end |
#==(other) ⇒ Object
Resolve some of the standard comparisons (with an OT or a hash)
207 |
# File 'lib/octothorpe.rb', line 207 def ==(other); compare_as_hash(other, :==); end |
#>(other) ⇒ Object
209 |
# File 'lib/octothorpe.rb', line 209 def >(other); compare_as_hash(other, :>); end |
#>=(other) ⇒ Object
210 |
# File 'lib/octothorpe.rb', line 210 def >=(other); compare_as_hash(other, :>=); end |
#>> ⇒ Object
:call-seq:
ot.>>.keyname
You can use >> to access member objects in somewhat the same way as an OpenStruct.
ot = Octothorpe.new(one: 1, "two" => 2)
ot.>>.one # -> 1
This will not work for members that have keys with spaces in, keys which have the same name as methods on Object, or keys that aren’t String or Symbol. Use get for those.
107 |
# File 'lib/octothorpe.rb', line 107 def >>; @store; end |
#get(key) ⇒ Object Also known as: send, []
:call-seq:
ot.get(key)
ot.send(key)
ot[key]
You can use get to access member object values instead of the >> syntax.
Unlike >>, this works for keys with spaces, or keys that have the same name as methods on Object.
121 |
# File 'lib/octothorpe.rb', line 121 def get(key); @store.octothorpe_store[octokey key]; end |
#guard(*args) ⇒ Object
:call-seq:
ot.guard( class, key [, key, ...] )
ot.guard( key, [,key, ...] ) {|k| ... }
Guarantees the initial state of a memnber. Each key that is not already present will be set to <class>.new. Has no effect if key is already present. Class must be some class Thing that can respond to a vanilla Thing.new.
Alternatively, for the block form, the key is passed to the block, and the value of the key becomes the return value of the block … but again, ONLY if the key is not already set.
Note that this is the only time that you can modify an Octothorpe object once it is created. If you call freeze on an it, it will become genuinely read-only, and any call to guard from then on will raise Octothorpe::Frozen.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/octothorpe.rb', line 149 def guard(*args) raise Frozen if self.frozen? klass = args.shift unless block_given? keys = args.map{|k| octokey k} if block_given? keys.each{|k| @store.octothorpe_store[k] ||= yield k } else keys.each{|k| @store.octothorpe_store[k] ||= klass.new } end self end |
#inspect ⇒ Object
Inspect exposes a view of the inner hash
217 218 219 |
# File 'lib/octothorpe.rb', line 217 def inspect "#<Octothorpe#{@store.octothorpe_store.inspect}>" end |
#merge(other) ⇒ Object
:call-seq:
ot.merge(other) -> new_ot
ot.merge(other){|key, oldval, newval| block} -> new_ot
Exactly as Hash.merge, but returns a new Octothorpe object.
You may pass a hash or an octothorpe. Raises Octothorpe::BadHash if it is anything else.
174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/octothorpe.rb', line 174 def merge(other) thisHash = @store.octothorpe_store otherHash = symbol_hash(other) merged = if block_given? thisHash.merge(otherHash) {|key,old,new| yield key, old, new } else thisHash.merge(otherHash) end Octothorpe.new(merged) end |
#to_h ⇒ Object
Returns a hash of the object.
130 |
# File 'lib/octothorpe.rb', line 130 def to_h; @store.octothorpe_store; end |
#whitelist(*keys) ⇒ Object
:call-seq:
ot.whitelist(:one, :two, :three) -> new_ot
Return an Octothorpe containing only these keys.
If you name a key that is missing, that key will also be missing in the output; use Guard if that’s not what you want.
198 199 200 |
# File 'lib/octothorpe.rb', line 198 def whitelist(*keys) Octothorpe.new @inner_hash.select{|k,_| symbol_hash(keys).include? k} end |