Class: Hash

Inherits:
Object show all
Defined in:
lib/jss/compatibility.rb,
lib/jss/ruby_extensions/hash.rb

Instance Method Summary collapse

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.

Examples:

hash = {:foo => '', :bar => {:baz => '' }}
hash.jss_nillify!  # {:foo => nil, :bar => {:baz => '' }}

hash = {:foo => '', :bar => {:baz => '' }}
hash.jss_nillify! '', :recurse  # {:foo => nil, :bar => {:baz => nil }}

hash = {:foo => 123, :bar => {:baz => '', :bim => "123" }}
hash.jss_nillify! ['', 123], :recurse # {:foo => nil, :bar => {:baz => nil, :bim => "123" }}

hash = {:foo => 123, :bar => {:baz => '', :bim => "123" }}
hash.jss_nillify!(:anything, :recurse){|v| v.to_i == 123 }  # {:foo => nil, :bar => {:baz => '', :bim => nil }}

Parameters:

  • to_nils (String, Array) (defaults to: '')

    Hash values equal to (==) these become nil. Defaults to empty string

  • recurse (Boolean) (defaults to: false)

    should sub-Hashes be nillified?

Yields:

  • (value)

    Hash values for which the block returns true will become nil.

Returns:

  • (Hash)

    the hash with the desired values converted to nil



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_ostructObject 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 Class 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 not it’s 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 be usually be considered read-only - and the RecursiveOpenStruct object created by this method should not be changed. Changes to the Hash or the RecursiveOpenStruct are NOT synced between them

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 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.



130
131
132
# File 'lib/jss/ruby_extensions/hash.rb', line 130

def jss_recursive_ostruct
  @jss_ros ||= RecursiveOpenStruct.new(self, recurse_over_arrays: true)
end