Class: Plist4r::Plist
Overview
See README and InfoPlistExample for usage examples. Also see EditingPlistFiles
Constant Summary collapse
- OptionsHash =
Recognised keys of the options hash. Passed when instantiating a new Plist Object
%w[filename path file_format plist_type strict_keys backends from_string]- FileFormats =
The plist file formats, written as symbols.
%w[binary xml gnustep]
Instance Method Summary collapse
-
#<<(*args, &blk) ⇒ Object
An alias of #edit.
-
#[](key) ⇒ Object
Element Reference — Retrieve the value object corresponding to the key object.
-
#[]=(key, value) ⇒ Object
Element Assignment — Assign a value to the given plist key.
-
#backends(backends = nil) ⇒ Array <Symbol>
An array of strings, symbols or class names which correspond to the active Plist4r::Backends for this object.
-
#clear ⇒ Object
Clears all plist keys and their contents.
-
#collect(&blk) ⇒ Object
Alias for #map.
-
#delete(*keys) ⇒ Object
Delete plist keys from the object.
-
#delete_if(*keys) { ... } ⇒ Object
Conditionally delete plist keys from the object.
-
#detect_plist_type ⇒ Object
Called automatically on plist load / instantiation.
-
#each { ... } ⇒ Object
This is equivalent to the ruby core classes method Hash#each.
-
#edit(*args, &blk) ⇒ Object
Edit a plist object.
-
#empty? ⇒ Boolean
This is equivalent to the ruby core classes method Array#empty?.
-
#file_format(file_format = nil) ⇒ Object
The file format of the plist file we are loading / saving.
-
#filename(filename = nil) ⇒ Object
Set or return the filename attribute of the plist object.
-
#filename_path(filename_path = nil) ⇒ Object
Set or return the combined filename+path.
-
#from_string(string = nil) ⇒ Object
Reinitialize plist object from string (overwrites the current contents).
-
#has_key?(key) ⇒ true, false
Alias of #include?.
-
#import_hash(hash = nil) ⇒ Object
Backend method to set or return all new plist data resulting from a backend API.
-
#include?(key) ⇒ true, false
Check if key exists in plist This is equivalent to the ruby core classes method Hash#include?.
-
#initialize(*args) { ... } ⇒ Plist4r::Plist
constructor
Instantiate a new Plist4r::Plist object.
-
#keys ⇒ Array <String, Symbol>
This is equivalent to the ruby core classes method Hash#keys.
-
#length ⇒ Object
This is equivalent to the ruby core classes method Array#length.
-
#map { ... } ⇒ Object
Invokes block &blk once for each key-value pair in plist.
-
#merge!(other_plist) ⇒ Object
Merge together plist objects.
-
#method_missing(method_sym, *args, &blk) ⇒ Object
Pass down unknown method calls to the selected plist_type, to set or return plist keys.
-
#open(filename = nil) ⇒ Plist4r::Plist
Opens a plist file.
-
#parse_opts(opts) ⇒ Object
Sets up those valid (settable) plist attributes as found the options hash.
-
#path(path = nil) ⇒ Object
Set or return the path attribute of the plist object.
-
#plist_type(plist_type = nil) ⇒ Object
Set or return the plist_type of the current object.
-
#save ⇒ Object
Save plist to #filename_path.
-
#save_as(filename) ⇒ Object
Save the plist under a new filename.
-
#select(*keys) { ... } ⇒ Object
Element selection - Keep selected plist keys and discard others.
-
#size ⇒ Object
This is equivalent to the ruby core classes method Array#size plist.size # => 14.
-
#store(key, value) ⇒ Object
Element Assignment — Assign a value to the given plist key.
-
#strict_keys(bool = nil) ⇒ Object
Set or return strict_keys mode.
-
#to_binary ⇒ Object
Write out a binary string representation of the plist.
-
#to_gnustep ⇒ Object
We are missing a backend for writing out plist strings in Gnustep / Nextstep / Openstep format.
-
#to_hash ⇒ Plist4r::OrderedHash
The internal data storage object for the plist data.
-
#to_xml ⇒ String
Export the plist to xml string representation.
-
#unselect(*keys) ⇒ Object
Alias for #delete.
Constructor Details
#initialize(*args) { ... } ⇒ Plist4r::Plist
Instantiate a new Plist4r::Plist object. We usually set our per-application defaults in Config beforehand.
Plist4r::Plist.new => #<Plist4r::Plist:0x111546c @file_format=nil, …> Plist4r::Plist.new(“example.plist”) => #<Plist4r::Plist:0x1152d1c @file_format=“xml”, …> plist_string = “{ "key1" = "value1"; "key2" = "value2"; }” Plist4r::Plist.new({ :from_string => plist_string })
=> #<Plist4r::Plist:0x11e161c @file_format="xml", ...>
plist_working_dir = ‘pwd`.strip Plist4r::Plist.new({ :filename => “example.plist”, :path => plist_working_dir, :backends => [“libxml4r”,“ruby_cocoa”]})
=> #<Plist4r::Plist:0x111546c @file_format=nil, ...>
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/plist4r/plist.rb', line 39 def initialize *args, &blk @hash = ::Plist4r::OrderedHash.new plist_type :plist @strict_keys = Config[:strict_keys] @backends = Config[:backends] @from_string = nil @filename = nil @file_format = nil @path = Config[:default_path] case args.first when Hash parse_opts args.first when String, Symbol @filename = args.first.to_s when nil else raise "Unrecognized first argument: #{args.first.inspect}" end @plist_cache ||= PlistCache.new self edit(&blk) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_sym, *args, &blk) ⇒ Object
Pass down unknown method calls to the selected plist_type, to set or return plist keys. All plist data manipulation API is called through method_missing -> PlistType -> DataMethods. plist.store “CFBundleVersion” “0.1.0”
337 338 339 |
# File 'lib/plist4r/plist.rb', line 337 def method_missing method_sym, *args, &blk eval "@plist_type.#{method_sym} *args, &blk" end |
Instance Method Details
#<<(*args, &blk) ⇒ Object
An alias of #edit
304 305 306 |
# File 'lib/plist4r/plist.rb', line 304 def << *args, &blk edit *args, &blk end |
#[](key) ⇒ Object
Element Reference — Retrieve the value object corresponding to the key object. If not found, returns nil
363 364 365 |
# File 'lib/plist4r/plist.rb', line 363 def [] key @plist_type.set_or_return key end |
#[]=(key, value) ⇒ Object
Element Assignment — Assign a value to the given plist key
375 376 377 |
# File 'lib/plist4r/plist.rb', line 375 def []= key, value store key, value end |
#backends(backends = nil) ⇒ Array <Symbol>
An array of strings, symbols or class names which correspond to the active Plist4r::Backends for this object. The priority order in which backends are executed is determined by the in sequence array order. Defaults to Plist4r::Config plist.backends [:haml, :ruby_cocoa]
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/plist4r/plist.rb', line 252 def backends backends=nil case backends when Array @backends = backends.collect do |b| case b when Symbol, String eval "Plist4r::Backend::#{b.to_s.camelcase}" b.to_sym when nil else raise "Backend #{b.inspect} is of unsupported type: #{b.class}" end end when nil @backends else raise "Please specify an array of valid Plist4r Backends" end end |
#clear ⇒ Object
Clears all plist keys and their contents
477 478 479 |
# File 'lib/plist4r/plist.rb', line 477 def clear @plist_type.array_dict :unselect_all end |
#collect(&blk) ⇒ Object
Alias for #map
440 441 442 |
# File 'lib/plist4r/plist.rb', line 440 def collect &blk map &blk end |
#delete(*keys) ⇒ Object
Delete plist keys from the object. Key names can be given as either snake_case’d Symbol or camelcased String
454 455 456 |
# File 'lib/plist4r/plist.rb', line 454 def delete *keys @plist_type.array_dict :unselect, *keys end |
#delete_if(*keys) { ... } ⇒ Object
Conditionally delete plist keys from the object.
467 468 469 470 471 |
# File 'lib/plist4r/plist.rb', line 467 def delete_if *keys, &blk delete *keys @hash.delete_if &blk @plist_type.to_hash @hash end |
#detect_plist_type ⇒ Object
Called automatically on plist load / instantiation. This method detects the “Plist Type”, using an algorithm that stats the plist data. The plist types with the highest stat (score) is chosen to be the object’s “Plist Type”.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/plist4r/plist.rb', line 166 def detect_plist_type stat_m = {} stat_r = {} Config[:types].each do |t| case t when String, Symbol t = eval "::Plist4r::PlistType::#{t.to_s.camelcase}" when Class t = t when nil else raise "Unrecognized plist type: #{t.inspect}" end t_sym = t.to_s.gsub(/.*:/,"").snake_case.to_sym stat_t = t.match_stat @hash.keys stat_m.store stat_t[:matches], t_sym stat_r.store stat_t[:ratio], t_sym end most_matches = stat_m.keys.sort.last if most_matches == 0 plist_type :plist elsif stat_m.keys.select{ |m| m == most_matches }.size > 1 most_matches = stat_r.keys.sort.last if stat_r.keys.select{ |m| m == most_matches }.size > 1 plist_type :plist else plist_type stat_r[most_matches] end else plist_type stat_m[most_matches] end end |
#each { ... } ⇒ Object
This is equivalent to the ruby core classes method Hash#each
523 524 525 |
# File 'lib/plist4r/plist.rb', line 523 def each &blk @hash.each &blk end |
#edit(*args, &blk) ⇒ Object
Edit a plist object. Set or return plist keys. Add or remove a selection of keys. Plist key accessor methods are snake-cased versions of the key string.
325 326 327 328 329 |
# File 'lib/plist4r/plist.rb', line 325 def edit *args, &blk @plist_type.to_hash @hash instance_eval *args, &blk detect_plist_type if plist_type == :plist end |
#empty? ⇒ Boolean
This is equivalent to the ruby core classes method Array#empty?
513 514 515 |
# File 'lib/plist4r/plist.rb', line 513 def empty? @hash.empty? end |
#file_format(file_format = nil) ⇒ Object
The file format of the plist file we are loading / saving. Written as a symbol. One of FileFormats. Defaults to :xml
146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/plist4r/plist.rb', line 146 def file_format file_format=nil case file_format when Symbol, String if FileFormats.include? file_format.to_s.snake_case @file_format = file_format.to_s.snake_case else raise "Unrecognized plist file format: \"#{file_format.inspect}\". Please specify a valid plist file format, #{FileFormats.inspect}" end when nil @file_format else raise "Please specify a valid plist file format, #{FileFormats.inspect}" end end |
#filename(filename = nil) ⇒ Object
Set or return the filename attribute of the plist object. Used in cojunction with the #path attribute
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/plist4r/plist.rb', line 97 def filename filename=nil case filename when String @filename = filename when nil @filename else raise "Please specify a filename" end end |
#filename_path(filename_path = nil) ⇒ Object
Set or return the combined filename+path. We use this method in the backends api as the full path to load / save
129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/plist4r/plist.rb', line 129 def filename_path filename_path=nil case filename_path when String @filename = File.basename filename_path @path = File.dirname filename_path when nil File. @filename, @path else raise "Please specify directory + filename" end end |
#from_string(string = nil) ⇒ Object
Reinitialize plist object from string (overwrites the current contents). Usually called from #initialize plist = Plist4r::Plist.new
=> #<Plist4r::Plist:0x11e161c @file_format=nil, ...>
plist.from_string “{ "key1" = "value1"; "key2" = "value2"; }”
=> #<Plist4r::Plist:0x11e161c @file_format="gnustep", ...>
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/plist4r/plist.rb', line 73 def from_string string=nil case string when String plist_format = Plist4r.string_detect_format(string) if plist_format @from_string = string @plist_cache ||= PlistCache.new self @plist_cache.from_string else raise "Unknown plist format for string: #{string}" end when nil @from_string else raise "Please specify a string of plist data" end end |
#has_key?(key) ⇒ true, false
Alias of #include?
507 508 509 510 |
# File 'lib/plist4r/plist.rb', line 507 def has_key? key key.to_s.camelcase if key.class == Symbol @hash.has_key? key end |
#import_hash(hash = nil) ⇒ Object
Backend method to set or return all new plist data resulting from a backend API. Used in load operations.
345 346 347 348 349 350 351 352 353 354 |
# File 'lib/plist4r/plist.rb', line 345 def import_hash hash=nil case hash when Plist4r::OrderedHash @hash = hash when nil @hash = ::Plist4r::OrderedHash.new else raise "Please use Plist4r::OrderedHash.new for your hashes" end end |
#include?(key) ⇒ true, false
Check if key exists in plist This is equivalent to the ruby core classes method Hash#include?
499 500 501 502 |
# File 'lib/plist4r/plist.rb', line 499 def include? key key.to_s.camelcase if key.class == Symbol @hash.include? key end |
#keys ⇒ Array <String, Symbol>
This is equivalent to the ruby core classes method Hash#keys
544 545 546 |
# File 'lib/plist4r/plist.rb', line 544 def keys @hash.keys end |
#length ⇒ Object
This is equivalent to the ruby core classes method Array#length
530 531 532 |
# File 'lib/plist4r/plist.rb', line 530 def length @hash.length end |
#map { ... } ⇒ Object
Invokes block &blk once for each key-value pair in plist. Similar to the ruby core classes Array#map. Replaces the plist keys and values with the [key,value] pairs returned by &blk. Key names can be given as either snake_case’d Symbol or camelcased String
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/plist4r/plist.rb', line 419 def map &blk if block_given? old_hash = @hash.deep_clone clear old_hash.each do |k,v| pair = yield k,v case pair when Array store pair[0], pair[1] when nil else raise "The supplied block must return plist [key, value] pairs, or nil" end end else raise "No block given" end end |
#merge!(other_plist) ⇒ Object
Merge together plist objects. Adds the contents of other_plist to the current object, overwriting any entries of the same key name with those from other_plist. Other attributes (filename, plist_type, file_format, etc) remain unaffected
485 486 487 488 489 490 491 492 493 |
# File 'lib/plist4r/plist.rb', line 485 def merge! other_plist if plist_type == other_plist.plist_type @hash.merge! other_plist.to_hash @plist_type.to_hash @hash else raise "plist_type differs, one is #{plist_type.inspect}, and the other is #{plist.plist_type.inspect}" end self end |
#open(filename = nil) ⇒ Plist4r::Plist
Opens a plist file
plist = Plist4r.new plist.open(“example.plist”) => #<Plist4r::Plist:0x1152d1c @file_format=“xml”, …>
292 293 294 295 296 |
# File 'lib/plist4r/plist.rb', line 292 def open filename=nil @filename = filename if filename raise "No filename specified" unless @filename @plist_cache.open end |
#parse_opts(opts) ⇒ Object
Sets up those valid (settable) plist attributes as found the options hash. Normally we dont call this method directly. Called from #initialize.
276 277 278 279 280 281 282 283 |
# File 'lib/plist4r/plist.rb', line 276 def parse_opts opts OptionsHash.each do |opt| if opts[opt.to_sym] value = opts[opt.to_sym] self.send opt, value end end end |
#path(path = nil) ⇒ Object
Set or return the path attribute of the plist object. Pre-pended to the plist’s filename (if filename is path-relative)
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/plist4r/plist.rb', line 112 def path path=nil case path when String @path = path when nil @path else raise "Please specify a directory" end end |
#plist_type(plist_type = nil) ⇒ Object
Set or return the plist_type of the current object. We can use this to override the automatic type detection.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/plist4r/plist.rb', line 206 def plist_type plist_type=nil begin case plist_type when Class # unless plist_type.is_a? ::Plist4r::PlistType # .is_a? returns false in spec unless plist_type.ancestors.include? Plist4r::PlistType raise "Unrecognized Plist type. Class #{plist_type.inspect} isnt inherited from ::Plist4r::PlistType" end when Symbol, String plist_type = eval "::Plist4r::PlistType::#{plist_type.to_s.camelcase}" when nil return @plist_type.to_sym else raise "Please specify a valid plist class name, eg ::Plist4r::PlistType::ClassName, \"class_name\" or :class_name" end @plist_type = plist_type.new self return @plist_type.to_sym rescue raise "Please specify a valid plist class name, eg ::Plist4r::PlistType::ClassName, \"class_name\" or :class_name" end end |
#save ⇒ Object
Save plist to #filename_path
607 608 609 610 |
# File 'lib/plist4r/plist.rb', line 607 def save raise "No filename specified" unless @filename @plist_cache.save end |
#save_as(filename) ⇒ Object
Save the plist under a new filename
615 616 617 618 |
# File 'lib/plist4r/plist.rb', line 615 def save_as filename @filename = filename save end |
#select(*keys) { ... } ⇒ Object
Element selection - Keep selected plist keys and discard others.
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/plist4r/plist.rb', line 393 def select *keys, &blk if block_given? selection = @hash.select &blk old_hash = @hash.deep_clone clear if RUBY_VERSION >= '1.9' selection.each do |key,value| store key, value end else selection.each do |pair| store pair[0], pair[1] end end keys.each do |k| store k, old_hash[k] end else @plist_type.array_dict :select, *keys end end |
#size ⇒ Object
This is equivalent to the ruby core classes method Array#size
plist.size # => 14
536 537 538 |
# File 'lib/plist4r/plist.rb', line 536 def size @hash.size end |
#store(key, value) ⇒ Object
Element Assignment — Assign a value to the given plist key
386 387 388 |
# File 'lib/plist4r/plist.rb', line 386 def store key, value @plist_type.set_or_return key, value end |
#strict_keys(bool = nil) ⇒ Object
Set or return strict_keys mode
232 233 234 235 236 237 238 239 240 241 |
# File 'lib/plist4r/plist.rb', line 232 def strict_keys bool=nil case bool when true,false @strict_keys = bool when nil @strict_keys else raise "Please specify true or false to enable / disable this option" end end |
#to_binary ⇒ Object
Write out a binary string representation of the plist
Looking for how to store a bytestream in CFData / NSData? See EditingPlistFiles
plist = “{ "key1" = "value1"; "key2" = "value2"; }”.to_plist plist.to_binary
=> "bplist00\322\001\002\003\004Tkey2Tkey1Vvalue2Vvalue1\b\r\022\027\036\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%"
595 596 597 |
# File 'lib/plist4r/plist.rb', line 595 def to_binary @plist_cache.to_binary end |
#to_gnustep ⇒ Object
We are missing a backend for writing out plist strings in Gnustep / Nextstep / Openstep format. Contributions appreciated.
600 601 602 |
# File 'lib/plist4r/plist.rb', line 600 def to_gnustep @plist_cache.to_gnustep end |
#to_hash ⇒ Plist4r::OrderedHash
The internal data storage object for the plist data
This is a pretty standard (either ActiveSupport or Ruby 1.9) ordered hash. Key names - regular ruby strings of arbitrary length.
Values - Must only store generic Ruby objects data such as TrueClass, FalseClass, Integer, Float, String, Time, Array, Hash, and Data
Data (NSData / CFData) - see EditingPlistFiles
plist = “{ "key1" = "value1"; "key2" = "value2"; }”.to_plist plist.to_hash => “key2”=>“value2”
562 563 564 |
# File 'lib/plist4r/plist.rb', line 562 def to_hash @hash end |
#to_xml ⇒ String
Export the plist to xml string representation. Calls through the plist cache
plist = “{ "key1" = "value1"; "key2" = "value2"; }”.to_plist plist.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>key1</key>\n\t<string>value1</string>\n\t<key>key2</key>\n\t<string>value2</string>\n</dict>\n</plist>"
583 584 585 |
# File 'lib/plist4r/plist.rb', line 583 def to_xml @plist_cache.to_xml end |