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
242 243 244 |
# File 'lib/gash.rb', line 242 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!
156 157 158 159 160 |
# File 'lib/gash.rb', line 156 def [](key, lazy = nil) ret = fetch(key, default) ensure ret.load! if ret.respond_to?(:load!) && !lazy end |
#==(other) ⇒ Object
246 247 248 249 250 251 252 |
# File 'lib/gash.rb', line 246 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!
151 152 153 154 155 |
# File 'lib/gash.rb', line 151 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
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/gash.rb', line 181 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
238 239 240 |
# File 'lib/gash.rb', line 238 def delete(key) super && changed! end |
#fetch(*args) ⇒ Object
:stopdoc:
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/gash.rb', line 214 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
254 255 256 257 |
# File 'lib/gash.rb', line 254 def merge(hash) tree = self.dup tree.merge!(hash) end |
#merge!(hash) ⇒ Object Also known as: update
259 260 261 262 263 264 |
# File 'lib/gash.rb', line 259 def merge!(hash) hash.each do |key, value| self[key] = value end self end |
#replace(hash) ⇒ Object
267 268 269 270 271 272 273 274 |
# File 'lib/gash.rb', line 267 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.
206 207 208 209 210 211 |
# File 'lib/gash.rb', line 206 def to_hash inject({}) do |memo, (key, value)| memo[key] = value.respond_to?(:to_hash) ? value.to_hash : value.to_s memo end end |