Module: Utils::ClassMethods

Included in:
Utils, Utils
Defined in:
lib/blueprint/utils.rb

Instance Method Summary collapse

Instance Method Details

#const_lookup(const, context = self) ⇒ Object

lookup a constant along the module nesting path



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/blueprint/utils.rb', line 140

def const_lookup(const, context = self)
  #p [:const_lookup, const, context]
  const = Utils.normalize_const(const)
  result = nil
  if !context.kind_of?(Module)
    context = context.class
  end
  klasses = context.to_s.split(/::/)
  #p klasses

  path = []
  0.upto(klasses.size - 1) do |i|
    path << Doodle::Utils.const_resolve(klasses[0..i].join('::'))
  end
  path = (path.reverse + context.ancestors).flatten
  #p [:const, context, path]
  path.each do |ctx|
    #p [:checking, ctx]
    if ctx.const_defined?(const)
      result = ctx.const_get(const)
      break
    end
  end
  if result.nil?
    raise NameError, "Uninitialized constant #{const} in context #{context}"
  else
    result
  end
end

#const_resolve(constant) ⇒ Object

resolve a constant of the form Some::Class::Or::Module - doesn’t work with constants defined in anonymous classes/modules



32
33
34
# File 'lib/blueprint/utils.rb', line 32

def const_resolve(constant)
  constant.to_s.split(/::/).reject{|x| x.empty?}.inject(Object) { |prev, this| prev.const_get(this) }
end

#deep_copy(obj) ⇒ Object

deep copy of object (unlike shallow copy dup or clone)



37
38
39
# File 'lib/blueprint/utils.rb', line 37

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

#doodle_callerObject

caller



116
117
118
119
120
121
122
# File 'lib/blueprint/utils.rb', line 116

def doodle_caller
  if $DEBUG
    caller
  else
    [caller[-1]]
  end
end

#flatten_first_level(enum) ⇒ Object

unnest arrays by one level of nesting, e.g. [1, [[2], 3]] => [1, [2], 3].



7
8
9
10
11
12
13
14
15
# File 'lib/blueprint/utils.rb', line 7

def flatten_first_level(enum)
  enum.inject([]) {|arr, i|
    if i.kind_of?(Array)
      arr.push(*i)
    else
      arr.push(i)
    end
  }
end

#normalize_const(const) ⇒ Object

normalize a name to contain only those characters which are valid for a Ruby constant



135
136
137
# File 'lib/blueprint/utils.rb', line 135

def normalize_const(const)
  const.to_s.gsub(/[^A-Za-z_0-9]/, '')
end

#normalize_keys(hash, recursive = false, method = :to_sym) ⇒ Object

normalize hash keys using method (e.g. :to_sym, :to_s)

  • returns copy of hash

  • optionally recurse into child hashes

see #normalize_keys! for details



68
69
70
71
72
73
74
75
# File 'lib/blueprint/utils.rb', line 68

def normalize_keys(hash, recursive = false, method = :to_sym)
  if recursive
    h = deep_copy(hash)
  else
    h = hash.dup
  end
  normalize_keys!(h, recursive, method)
end

#normalize_keys!(hash, recursive = false, method = :to_sym) ⇒ Object

normalize hash keys using method (e.g. :to_sym, :to_s)

hash

target hash to update

recursive

recurse into child hashes if true (default is not to recurse)

method

method to apply to key (default is :to_sym)



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/blueprint/utils.rb', line 46

def normalize_keys!(hash, recursive = false, method = :to_sym)
  if hash.kind_of?(Hash)
    hash.keys.each do |key|
      normalized_key = key.respond_to?(method) ? key.send(method) : key
      v = hash.delete(key)
      if recursive
        if v.kind_of?(Hash)
          v = normalize_keys!(v, recursive, method)
        elsif v.kind_of?(Array)
          v = v.map{ |x| normalize_keys!(x, recursive, method) }
        end
      end
      hash[normalized_key] = v
    end
  end
  hash
end

#pluralize(string) ⇒ Object

simple (!) pluralization - if you want fancier, override this method



106
107
108
109
110
111
112
113
# File 'lib/blueprint/utils.rb', line 106

def pluralize(string)
  s = string.to_s
  if s =~ /s$/
    s + 'es'
  else
    s + 's'
  end
end

#snake_case(camel_cased_word) ⇒ Object Also known as: snakecase

convert a CamelCasedWord to a snake_cased_word based on version in facets/string/case.rb, line 80



19
20
21
22
23
24
25
26
# File 'lib/blueprint/utils.rb', line 19

def snake_case(camel_cased_word)
  # if all caps, just downcase it
  if camel_cased_word =~ /^[A-Z]+$/
    camel_cased_word.downcase
  else
    camel_cased_word.to_s.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
  end
end

#stringify_keys(hash, recursive = false) ⇒ Object

convert keys to strings

  • returns copy of hash

  • optionally recurse into child hashes



101
102
103
# File 'lib/blueprint/utils.rb', line 101

def stringify_keys(hash, recursive = false)
  normalize_keys(hash, recursive, :to_s)
end

#stringify_keys!(hash, recursive = false) ⇒ Object

convert keys to strings

  • updates target hash in place

  • optionally recurse into child hashes



94
95
96
# File 'lib/blueprint/utils.rb', line 94

def stringify_keys!(hash, recursive = false)
  normalize_keys!(hash, recursive, :to_s)
end

#symbolize_keys(hash, recursive = false) ⇒ Object

convert keys to symbols

  • returns copy of hash

  • optionally recurse into child hashes



87
88
89
# File 'lib/blueprint/utils.rb', line 87

def symbolize_keys(hash, recursive = false)
  normalize_keys(hash, recursive, :to_sym)
end

#symbolize_keys!(hash, recursive = false) ⇒ Object

convert keys to symbols

  • updates target hash in place

  • optionally recurse into child hashes



80
81
82
# File 'lib/blueprint/utils.rb', line 80

def symbolize_keys!(hash, recursive = false)
  normalize_keys!(hash, recursive, :to_sym)
end

#try(&block) ⇒ Object

execute block - catch any exceptions and return as value



125
126
127
128
129
130
131
# File 'lib/blueprint/utils.rb', line 125

def try(&block)
  begin
    block.call
  rescue Exception => e
    e
  end
end