Module: Boson::Util

Extended by:
Util
Included in:
Util
Defined in:
lib/boson/util.rb

Overview

Collection of utility methods used throughout Boson.

Instance Method Summary collapse

Instance Method Details

#any_const_get(name) ⇒ Object

Returns a constant like const_get() no matter what namespace it’s nested in. Returns nil if the constant is not found.



29
30
31
# File 'lib/boson/util.rb', line 29

def any_const_get(name)
  Hirb::Util.any_const_get(name)
end

#camelize(string) ⇒ Object

From Rails ActiveSupport, does the reverse of underscore: ‘boson/method_inspector’ -> ‘Boson::MethodInspector’



17
18
19
# File 'lib/boson/util.rb', line 17

def camelize(string)
  Hirb::Util.camelize(string)
end

#constantize(string) ⇒ Object

Converts a module/class string to the actual constant. Returns nil if not found.



23
24
25
# File 'lib/boson/util.rb', line 23

def constantize(string)
  any_const_get(camelize(string))
end

#create_module(base_module, name) ⇒ Object

Creates a module under a given base module and possible name. If the module already exists or conflicts per top_level_class_conflict, it attempts to create one with a number appended to the name.



71
72
73
74
75
76
77
78
# File 'lib/boson/util.rb', line 71

def create_module(base_module, name)
  desired_class = camelize(name)
  possible_suffixes = [''] + %w{1 2 3 4 5 6 7 8 9 10}
  if (suffix = possible_suffixes.find {|e| !base_module.const_defined?(desired_class+e) &&
    !top_level_class_conflict(base_module, "#{base_module}::#{desired_class}#{e}") })
    base_module.const_set(desired_class+suffix, Module.new)
  end
end

#deep_copy(obj) ⇒ Object

Deep copies any object if it can be marshaled. Useful for deep hashes.



86
87
88
# File 'lib/boson/util.rb', line 86

def deep_copy(obj)
  Marshal::load(Marshal::dump(obj))
end

#detect(options = {}, &block) ⇒ Object

Detects new object/kernel methods, gems and modules created within a block. Returns a hash of what’s detected. Valid options and possible returned keys are :methods, :object_methods, :modules, :gems.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/boson/util.rb', line 36

def detect(options={}, &block)
  options = {:methods=>true, :object_methods=>true}.merge!(options)
  original_gems = Object.const_defined?(:Gem) ? Gem.loaded_specs.keys : []
  original_object_methods = Object.instance_methods
  original_instance_methods = class << Boson.main_object; instance_methods end
  original_modules = modules if options[:modules]
  block.call
  detected = {}
  detected[:methods] = options[:methods] ? (class << Boson.main_object; instance_methods end -
    original_instance_methods) : []
  detected[:methods] -= (Object.instance_methods - original_object_methods) unless options[:object_methods]
  detected[:gems] = Gem.loaded_specs.keys - original_gems if Object.const_defined? :Gem
  detected[:modules] = modules - original_modules if options[:modules]
  detected
end

#find_homeObject

From Rubygems, determine a user’s home.



96
97
98
# File 'lib/boson/util.rb', line 96

def find_home
  Hirb::Util.find_home
end

#modulesObject

Returns all modules that currently exist.



63
64
65
66
67
# File 'lib/boson/util.rb', line 63

def modules
  all_modules = []
  ObjectSpace.each_object(Module) {|e| all_modules << e}
  all_modules
end

#recursive_hash_merge(hash1, hash2) ⇒ Object

Recursively merge hash1 with hash2.



91
92
93
# File 'lib/boson/util.rb', line 91

def recursive_hash_merge(hash1, hash2)
  hash1.merge(hash2) {|k,o,n| (o.is_a?(Hash)) ? recursive_hash_merge(o,n) : n}
end

#safe_require(lib) ⇒ Object

Safely calls require, returning false if LoadError occurs.



53
54
55
56
57
58
59
60
# File 'lib/boson/util.rb', line 53

def safe_require(lib)
  begin
    require lib
    true
  rescue LoadError
    false
  end
end

#split_array_by(arr, divider) ⇒ Object

Splits array into array of arrays with given element



107
108
109
110
111
112
# File 'lib/boson/util.rb', line 107

def split_array_by(arr, divider)
  arr.inject([[]]) {|results, element|
    (divider == element) ? (results << []) : (results.last << element)
    results
  }
end

#top_level_class_conflict(base_module, conflicting_module) ⇒ Object

Returns name of top level class that conflicts if it exists. For example, for base module Boson::Commands, Boson::Commands::Alias conflicts with Alias if Alias exists.



102
103
104
# File 'lib/boson/util.rb', line 102

def top_level_class_conflict(base_module, conflicting_module)
  (conflicting_module =~ /^#{base_module}.*::([^:]+)/) && Object.const_defined?($1) && $1
end

#underscore(camel_cased_word) ⇒ Object

From Rails ActiveSupport, converts a camelcased string to an underscored string: ‘Boson::MethodInspector’ -> ‘boson/method_inspector’



7
8
9
10
11
12
13
# File 'lib/boson/util.rb', line 7

def underscore(camel_cased_word)
  camel_cased_word.to_s.gsub(/::/, '/').
   gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
   gsub(/([a-z\d])([A-Z])/,'\1_\2').
   tr("-", "_").
   downcase
end

#underscore_search(input, list, first_match = false) ⇒ Object

Regular expression search of a list with underscore anchoring of words. For example ‘some_dang_long_word’ can be specified as ‘s_d_l_w’.



116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/boson/util.rb', line 116

def underscore_search(input, list, first_match=false)
  meth = first_match ? :find : :select
  return (first_match ? input : [input]) if list.include?(input)
  input = input.to_s
  if input.include?("_")
    underscore_regex = input.split('_').map {|e| Regexp.escape(e) }.join("([^_]+)?_")
    list.send(meth) {|e| e.to_s =~ /^#{underscore_regex}/ }
  else
    escaped_input = Regexp.escape(input)
    list.send(meth) {|e| e.to_s =~ /^#{escaped_input}/ }
  end
end

#which(command) ⇒ Object

Behaves just like the unix which command, returning the full path to an executable based on ENV.



81
82
83
# File 'lib/boson/util.rb', line 81

def which(command)
  ENV['PATH'].split(File::PATH_SEPARATOR).map {|e| File.join(e, command) }.find {|e| File.exists?(e) }
end