Class: Hash
- Includes:
- JamfRubyExtensions::Hash::BackPorts, RubyDig
- Defined in:
- lib/jamf/ruby_extensions/dig.rb,
lib/jss/compatibility.rb,
lib/jamf/compatibility.rb,
lib/jss/ruby_extensions/hash.rb,
lib/jamf/ruby_extensions/hash.rb
Overview
include the modules loaded above
Instance Method Summary collapse
- #dig(key, *rest) ⇒ Object included from RubyDig
-
#jss_nillify!(to_nils = '', recurse = false) {|value| ... } ⇒ Hash
Convert Hash values to nil.
-
#jss_recursive_ostruct ⇒ Object
(also: #jss_ros)
Since a lot of JSON data from the API comes as deeply-nested structures of Hashes and Arrays, it can be a pain to reference some of the deeper data inside, and it isn't worth coding them out into instance attributes.
- #transform_keys(&block) ⇒ Object included from JamfRubyExtensions::Hash::BackPorts
- #transform_keys!(&block) ⇒ Object included from JamfRubyExtensions::Hash::BackPorts
- #transform_values(&block) ⇒ Object included from JamfRubyExtensions::Hash::BackPorts
- #transform_values!(&block) ⇒ Object included from JamfRubyExtensions::Hash::BackPorts
Instance Method Details
#jss_nillify!(to_nils = '', recurse = false) {|value| ... } ⇒ Hash
Convert Hash values to nil.
With no block, values equalling the String, or any member of the Array, given will be converted to nil. Equality is evaluated with == and Array#include?
With a block, if the result of the block evaluates to true, the value is converted to nil.
Subhashes are ignored unless recurse is true.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/jss/ruby_extensions/hash.rb', line 60 def jss_nillify!(to_nils = '', recurse = false, &block) nillify_these = [] << to_nils nillify_these.flatten! each_pair do |k, v| if v.class == Hash v.jss_nillify!(to_nils, recurse, &block) next end do_it = if block_given? yield v else nillify_these.include? v end self[k] = nil if do_it end # each pair end |
#jss_recursive_ostruct ⇒ Object Also known as: jss_ros
Since a lot of JSON data from the API comes as deeply-nested structures of Hashes and Arrays, it can be a pain to reference some of the deeper data inside, and it isn't worth coding them out into instance attributes.
For example see the 'hardware' subset of a JSS::Computer's API data, which is stored as a Hash in the JSS::Computer#hardware attribute.
To refer to the percent-full value of one of the machine's drives, you need to use e.g. this:
computer_instance.hardware[:storage].first[:partition][:percentage_full]
It would be nice to use method-like chains to access that data, similar to what OpenStruct provides.
But, there are two problems with just storing #hardware as an OpenStruct: 1) we'd lose some important Hash methods, like #keys and #values, breaking backward compatibility. 2) OpenStructs only work on the Hash itself, not its contents.
So to get the best of both worlds, we use the RecursiveOpenStruct gem
https://github.com/aetherknight/recursive-open-struct
which subclasses OpenStruct to be recursive.
And, instead of replacing the Hash, we'll add a RecursiveOpenStruct version of itself to itself as an attribute.
Now, we can access the same data using this:
computer_instance.hardware.jss_ros.storage.first.partition.percentage_full
CAVEAT: Treat these as read-only.
While the Hashes themselves may be mutable, their use in ruby-jss Classes should usually be considered read-only - neither the Hash, nor the RecursiveOpenStruct object created by this method should be changed. Changes to the Hash or the RecursiveOpenStruct are NOT synced between them, and ruby-jss won't know to send such changes back to the API when #update is called.
This should be fine for the intended uses. Data like Computer#hardware isn't sent back to the JSS via Computer#update, since it must come from a 'recon' anyway.
Data that is sent back to the JSS will have setter methods defined in the class or a mixin module (e.g. the Locatable module).
Since the data is functionally read-only, why not use the ImmutableStruct gem, used elsewhere in ruby-jss?
Because ImmutableStruct is really for creating fully-fleshed-out read-only classes, with a known set of attributes rather than just giving us a nicer way to access Hash data with arbitrary keys.
135 136 137 |
# File 'lib/jss/ruby_extensions/hash.rb', line 135 def jss_recursive_ostruct @jss_ros ||= RecursiveOpenStruct.new(self, recurse_over_arrays: true) end |