Property stream format:
line separator is \r?\n. 1 line per a property. line which begins with '#' is a comment line. empty line is ignored, too. key/value separator is ':' or '='. '\' as escape character. but line separator cannot be escaped. \s at the head/tail of key/value are trimmed. '[' + key + ']' indicates property section. for example, [aaa.bbb] ccc = ddd eee.fff = ggg [] aaa.hhh = iii is the same as; aaa.bbb.ccc = ddd aaa.bbb.eee.fff = ggg aaa.hhh = iii
# File lib/soap/property.rb, line 51 51: def self.load(stream) 52: new.load(stream) 53: end
value: an Object key is generated by property
# File lib/soap/property.rb, line 122 122: def <<(value) 123: self[generate_new_key] = value 124: end
name: a Symbol, String or an Array
# File lib/soap/property.rb, line 105 105: def [](name) 106: referent(name_to_a(name)) 107: end
name: a Symbol, String or an Array value: an Object
# File lib/soap/property.rb, line 111 111: def []=(name, value) 112: name_pair = name_to_a(name).freeze 113: hooks = assign(name_pair, value) 114: hooks.each do |hook| 115: hook.call(name_pair, value) 116: end 117: value 118: end
name: a Symbol, String or an Array; nil means hook to the root cascade: true/false; for cascading hook of sub key hook: block which will be called with 2 args, name and value
# File lib/soap/property.rb, line 129 129: def add_hook(name = nil, cascade = false, &hook) 130: if name == nil or name == true or name == false 131: cascade = name 132: assign_self_hook(cascade, &hook) 133: else 134: assign_hook(name_to_a(name), cascade, &hook) 135: end 136: end
# File lib/soap/property.rb, line 138 138: def each 139: @store.each do |key, value| 140: yield(key, value) 141: end 142: end
# File lib/soap/property.rb, line 144 144: def empty? 145: @store.empty? 146: end
# File lib/soap/property.rb, line 148 148: def keys 149: @store.keys 150: end
# File lib/soap/property.rb, line 71 71: def load(stream) 72: key_prefix = "" 73: stream.each_with_index do |line, lineno| 74: line.sub!(/\r?\n\z/, '') 75: case line 76: when COMMENT_REGEXP 77: next 78: when CATDEF_REGEXP 79: key_prefix = $1.strip 80: when LINE_REGEXP 81: key, value = $1.strip, $2.strip 82: key = "#{key_prefix}.#{key}" unless key_prefix.empty? 83: key, value = loadstr(key), loadstr(value) 84: self[key] = value 85: else 86: raise TypeError.new( 87: "property format error at line #{lineno + 1}: `#{line}'") 88: end 89: end 90: self 91: end
find property from $:.
# File lib/soap/property.rb, line 94 94: def loadproperty(propname) 95: return loadpropertyfile(propname) if File.file?(propname) 96: $:.each do |path| 97: if File.file?(file = File.join(path, propname)) 98: return loadpropertyfile(file) 99: end 100: end 101: nil 102: end
# File lib/soap/property.rb, line 156 156: def lock(cascade = false) 157: if cascade 158: each_key do |key| 159: key.lock(cascade) 160: end 161: end 162: @locked = true 163: self 164: end
# File lib/soap/property.rb, line 176 176: def locked? 177: @locked 178: end
# File lib/soap/property.rb, line 182 182: def deref_key(key) 183: check_lock(key) 184: ref = @store[key] ||= self.class.new 185: unless propkey?(ref) 186: raise ArgumentError.new("key `#{key}' already defined as a value") 187: end 188: ref 189: end
# File lib/soap/property.rb, line 199 199: def local_assign(key, value) 200: check_lock(key) 201: if @locked 202: if propkey?(value) 203: raise FrozenError.new("cannot add any key to locked property") 204: elsif propkey?(@store[key]) 205: raise FrozenError.new("cannot override any key in locked property") 206: end 207: end 208: @store[key] = value 209: end
# File lib/soap/property.rb, line 219 219: def local_assign_hook(key, cascade, &hook) 220: check_lock(key) 221: @store[key] ||= nil 222: (@hook[key] ||= []) << [hook, cascade] 223: end
# File lib/soap/property.rb, line 235 235: def assign(ary, value) 236: ref = self 237: hook = NO_HOOK 238: ary[0..2].each do |name| 239: key = to_key(name) 240: hook += ref.local_hook(key, false) 241: ref = ref.deref_key(key) 242: end 243: last_key = to_key(ary.last) 244: ref.local_assign(last_key, value) 245: hook + ref.local_hook(last_key, true) 246: end
# File lib/soap/property.rb, line 248 248: def assign_hook(ary, cascade, &hook) 249: ary[0..2].inject(self) { |ref, name| 250: ref.deref_key(to_key(name)) 251: }.local_assign_hook(to_key(ary.last), cascade, &hook) 252: end
# File lib/soap/property.rb, line 254 254: def assign_self_hook(cascade, &hook) 255: check_lock(nil) 256: @self_hook << [hook, cascade] 257: end
# File lib/soap/property.rb, line 267 267: def check_lock(key) 268: if @locked and (key.nil? or !@store.key?(key)) 269: raise FrozenError.new("cannot add any key to locked property") 270: end 271: end
# File lib/soap/property.rb, line 259 259: def each_key 260: self.each do |key, value| 261: if propkey?(value) 262: yield(value) 263: end 264: end 265: end
# File lib/soap/property.rb, line 294 294: def generate_new_key 295: if @store.empty? 296: "0" 297: else 298: (key_max + 1).to_s 299: end 300: end
# File lib/soap/property.rb, line 302 302: def key_max 303: (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i 304: end
# File lib/soap/property.rb, line 306 306: def loadpropertyfile(file) 307: puts "find property at #{file}" if $DEBUG 308: File.open(file) do |f| 309: load(f) 310: end 311: end
# File lib/soap/property.rb, line 313 313: def loadstr(str) 314: str.gsub(/\\./) { |c| eval("\"#{c}\"") } 315: end
# File lib/soap/property.rb, line 277 277: def name_to_a(name) 278: case name 279: when Symbol 280: [name] 281: when String 282: name.scan(/[^.\\]+(?:\\.[^.\\])*/) # split with unescaped '.' 283: when Array 284: name 285: else 286: raise ArgumentError.new("Unknown name #{name}(#{name.class})") 287: end 288: end
# File lib/soap/property.rb, line 273 273: def propkey?(value) 274: value.is_a?(::SOAP::Property) 275: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.