module SknUtils
##
See JobCommands, HttpProcessor
, … See ./bin/par_test_ examples
File: <gem-root>/lib/skn_utils/configurable.rb
Ref: https://www.toptal.com/ruby/ruby-dsl-metaprogramming-guide
## lib/skn_utils/configuration.rb
@see SknSettings
Filepath Targets:
<prepend-somefile> config/settings.yml config/settings/#{environment}.yml config/environments/#{environment}.yml
config/settings.local.yml config/settings/#{environment}.local.yml config/environments/#{environment}.local.yml <append-somefile>
Public API
load_config_basename!(environment_name) config_path!(config_root) load_and_set_settings(ordered_list_of_files)
- Alias: reload_from_files(ordered_list_of_files)
reload!() setting_files(config_root, environment_name) add_source!(file_path_or_hash) prepend_source!(file_path_or_hash)
SknSettings setup: class << (SknSetting = SknUtils::Configuration.new
( ENV )); end
## File: ./lib/skn_utils/core_extensions.rb – – from: Rails 4.1 ActiveSupport:lib/active_support/core_ext/object/blank.rb – Ref: 6ftdan.com/allyourdev/2015/01/20/refinements-over-monkey-patching/ – Ref: medium.com/rubycademy/the-complete-guide-to-create-a-copy-of-an-object-in-ruby-part-ii-cd28a99d58d9
File: ./lib/skn_utils/env_string_handler.rb
Wrapping a string in this class gives you a prettier way to test for equality. The value returned by Rails.env
is wrapped in a StringInquirer object so instead of calling this:
Rails.env == 'production' SknSettings.env == 'production'
you can call this:
Rails.env.production? SknSettings.env.productcion?
Create a EnvStringHandler
to support: SknSettings.env.development? Yes, its YAML trick in config/settings.yml
... env: !ruby/string:SknUtils::EnvStringHandler <%= ENV['RACK_ENV'] %> root: !ruby/string:SknUtils::EnvStringHandler <%= Dir.pwd %> ...
#
##
Ref: yukimotopress.github.io/http
<project.root>/lib/skn_utils/nested_result.rb
SknUtils::NestedResult
Value Container/Class for Ruby with Indifferent Hash
and/or Dot.notation access
Description:
Creates an Object
with attribute methods for dot.notation and hash.notation access for each hash input key/value pair.
If the key's value is an hash itself, it will become an NestedResult Object. if the key's value is an Array of Hashes, each hash element of the Array will become an Object; non-hash object are left as-is if the key's value is an Array of Arrays-of- Hash/Object, each hash element of each Array will become an Object; non-hash object are left as-is. This array of array of arrays goes on to the end. Transforms entire input hash contents into dot.notation and hash.notation accessible key/value pairs. - hash - array of hashes - non hash element values are not modified, whether in an array or the basic value in a key/value pair
The ability of the resulting Object
to be YAML/Psych'ed, or Marshaled(dump/load) is preserved
Transforms entire input hash contents into dot.notation accessible object
- hash - array of hashes - non hash element values are not modified, whether in an array or the basic value in a key/value pair
This module provides
Simple Initialization Pattern
person = SknUtils::NestedResult.new( {name: "Bob", title: {day: 'Analyst', night: 'Fireman'}} )
Serializers:
person.to_hash => {name: 'Bob', title: {day: 'Analyst', night: 'Fireman'}} person.to_json => "{\"name\":\"Bob\", \"title\":{\"day\":\"Analyst\", \"night\":\"Fireman\"}}"
Dynamic addition of new key/values after initialization
person.address = 'Fort Wayne Indiana' person.address => 'Fort Wayne Indiana'
dot.notation feature for all instance variables
person.title.day => "Analyst" person.name = "James" => "James"
InDifferent String/Symbol hash feature for all instance variables
person['title']['day'] => "Analyst" person['name'] = "James" => "James" person[:name] => "James" person[:name] = "Bob" => "Bob"
Supports <attr>? predicate method patterns, and delete_field(:attr) method
example: person.title.night? => true true or false, like obj.name.present? person.delete_field(:name) only first/root level attributes can be deleted => 'Bob' returns last value of deleted key person.name_not_found => NoMethodFound raises exception if key is not found
Exporting hash from any key starting point
person.hash_from(:name) => {name: 'Bob'} the entire hash tree from that starting point
Advanced Methods
#to_hash - returns copy of input hash #to_json(*args) - converts input hash into JSON #keys - returns the first-level keys of input hash #delete_field(attr_sym) - removes attribute/key and returns it's former value #hash_from(starting_attr_sym) - (Protected Method) returns remaining hash starting from key provided
Known Issues
-
Fixnum keys work as keys with the exception of respond_to?() which does not support them
-
Entries with Fixnums or object-instance keys are accessible only via []=(), [] Hash.notation
methods and not the dot.notation feature
Ruby Notify like class
Ref: ozone.wordpress.com/category/programming/metaprogramming/
Listeners implement:
def attribute_changed(attr, old, new) ... end
lib/skn_utils/null_object.rb
A better way to say it
##
Ref: blog.appsignal.com/2018/10/02/ruby-magic-class-level-instance-variables.html
Constants
- VERSION
Public Class Methods
## SknUtils.as_human_size(12345)
#=> 12 KB
# File lib/skn_utils.rb, line 76 def self.as_human_size(number) units = %W(Bytes KB MB GB TB PB EB) num = number.to_f if number < 1001 num = number exp = 0 else max_exp = units.size - 1 exp = ( Math.log( num ) / Math.log( 1024 ) ).round exp = max_exp if exp > max_exp num /= 1024 ** exp end ((num > 9 || num.modulo(1) < 0.1) ? '%d %s' : '%.1f %s') % [num, units[exp]] end
Random Utils Retries block up to :retries times with a :pause_between, and returns Success/Failure object – return SknSuccess
| SknFailure
response object
# File lib/skn_utils.rb, line 52 def self.catch_exceptions(retries=3, pause_between=3, &block) retry_count ||= 1 attempts = retries begin res = yield [SknFailure, SknFailure].any? {|o| res.kind_of?(o) } ? res : SknSuccess.( res ) rescue StandardError, ScriptError => error $stderr.puts "#{retry_count} - #{error.class.name}:#{error.message}" if retry_count <= attempts retry_count+= 1 sleep(pause_between) retry else SknFailure.( "RETRY ATTEMPTS FAILED - #{error.class.name}:#{error.message}", error.backtrace[0..5].to_s ) end end end
call without to get start time call with start_time to get duration string
# File lib/skn_utils.rb, line 93 def self.duration(start_time=nil) start_time.nil? ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : "%3.3f seconds" % (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) end
# File lib/skn_utils/null_object.rb, line 27 def self.nullable?(value) value.nil? ? NullObject.new : value end