Class: Gash::Tree
Overview
A Tree is a Hash which can store other instances of Tree and Blob.
Special methods
Internally, a tree is being stored like this:
{
"README" => blob,
"examples" => {
"test.rb" => blob,
"yay.rb" => blob
}
}
So you have to do tree["examples"].delete("test.rb")
instead of tree.delete("examples/test.rb")
. However, there are some methods which supports the slash. All of these will work:
tree["examples/test.rb"]
tree.fetch("examples/test.rb")
tree["examples/another.rb"] = "Content"
tree.store("examples/another.rb", "Content") # Exactly the same as above.
tree["examples"]["test.rb"] # Or, you could use this
Documentation
The point of Tree is that it should be as close to Hash as possible. Therefore, methods which behaves exactly equally in Gash and Hash will not be documentated below. Please see the Ruby documentation if you wonder what you can do.
See also: Helpers, Blob
Instance Attribute Summary
Attributes included from Helpers
Class Method Summary collapse
Instance Method Summary collapse
-
#/ ⇒ Object
Retrieves the value stored as
key
:. - #==(other) ⇒ Object
-
#[](key, lazy = nil) ⇒ Object
Retrieves the value stored as
key
:. -
#[]=(key, value, not_changed = nil) ⇒ Object
(also: #store)
Stores the given value at
key
:. - #delete(key) ⇒ Object
-
#fetch(*args) ⇒ Object
:stopdoc:.
- #merge(hash) ⇒ Object
- #merge!(hash) ⇒ Object (also: #update)
- #replace(hash) ⇒ Object
-
#to_hash ⇒ Object
Converts the tree to a Hash.
Methods included from Helpers
#blob?, #changed!, #changed?, #gash, #initialize, #normalize, #tree?
Class Method Details
.[](*val) ⇒ Object
262 263 264 |
# File 'lib/gash.rb', line 262 def self.[](*val) new.merge!(Hash[*val]) end |
Instance Method Details
#/ ⇒ Object
Retrieves the value stored as key
:
tree["FILE"] == File.read("FILE")
tree["DIR/FILE"] == tree["DIR"]["FILE"] == File.read("DIR/FILE")
Lazy loading
By default, this method will automatically load the blob/tree from the repo. If you rather want to load it later, simply set lazy
to true
:
blob = tree["FILE", true]
# do some other stuff...
blob.load! # Load it now!
176 177 178 179 180 |
# File 'lib/gash.rb', line 176 def [](key, lazy = nil) ret = fetch(key, default) ensure ret.load! if ret.respond_to?(:load!) && !lazy end |
#==(other) ⇒ Object
266 267 268 269 270 271 272 |
# File 'lib/gash.rb', line 266 def ==(other) if other.is_a?(Tree) && sha1 && other.sha1 sha1 == other.sha1 else super end end |
#[](key, lazy = nil) ⇒ Object
Retrieves the value stored as key
:
tree["FILE"] == File.read("FILE")
tree["DIR/FILE"] == tree["DIR"]["FILE"] == File.read("DIR/FILE")
Lazy loading
By default, this method will automatically load the blob/tree from the repo. If you rather want to load it later, simply set lazy
to true
:
blob = tree["FILE", true]
# do some other stuff...
blob.load! # Load it now!
171 172 173 174 175 |
# File 'lib/gash.rb', line 171 def [](key, lazy = nil) ret = fetch(key, default) ensure ret.load! if ret.respond_to?(:load!) && !lazy end |
#[]=(key, value, not_changed = nil) ⇒ Object Also known as: store
Stores the given value at key
:
tree["FILE"] = "Content"
It uses Helpers#normalize in order convert it to a blob/tree, and will always set the parent to itself:
tree["FILE"] = "Content"
# is the same as:
tree["FILE"] = Gash::Blob.new(:content => "Content", :parent => tree)
Mark as changed
By default, the object will be marked as changed (using Helpers#changed!
). If this is not what you want, simply set not_changed
to true
.
However, if you give it three arguments, then the second one will act as not_changed
, not the third:
1 2 3
tree["FILE", true] = "Test"
tree["FILE"].changed? # => false
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/gash.rb', line 201 def []=(key, value, not_changed = nil) key, value, not_changed = if not_changed.nil? [key, value] else [key, not_changed, value] end if key.include?("/") keys = key.split("/") name = keys.pop keys.inject(self) do |memo, i| memo[i, not_changed] = Tree.new(:parent => self) unless memo.include?(i) memo[i, true] end[name, not_changed] = value else value = normalize(value) value.parent = self super(key, value) end ensure self.changed! unless not_changed end |
#delete(key) ⇒ Object
258 259 260 |
# File 'lib/gash.rb', line 258 def delete(key) super && changed! end |
#fetch(*args) ⇒ Object
:stopdoc:
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/gash.rb', line 234 def fetch(*args) key = args.first.to_s case args.length when 1 r = true when 2 r = false default = args.last else raise ArgumentError, "wrong number of arguments (#{args.length} for 2)" end if key.include?("/") key, rest = key.split("/", 2) value = super(key) value.fetch(rest) else super(key) end rescue IndexError => e (r && raise(e)) || default end |
#merge(hash) ⇒ Object
274 275 276 277 |
# File 'lib/gash.rb', line 274 def merge(hash) tree = self.dup tree.merge!(hash) end |
#merge!(hash) ⇒ Object Also known as: update
279 280 281 282 283 284 |
# File 'lib/gash.rb', line 279 def merge!(hash) hash.each do |key, value| self[key] = value end self end |
#replace(hash) ⇒ Object
287 288 289 290 291 292 293 294 |
# File 'lib/gash.rb', line 287 def replace(hash) if hash.is_a?(Gash::Tree) super else clear merge!(hash) end end |
#to_hash ⇒ Object
Converts the tree to a Hash.
226 227 228 229 230 231 |
# File 'lib/gash.rb', line 226 def to_hash inject({}) do |memo, (key, value)| memo[key] = value.respond_to?(:to_hash) ? value.to_hash : value.to_s memo end end |