Module: Doodle::Utils::ClassMethods

Included in:
Doodle::Utils, Doodle::Utils
Defined in:
lib/doodle/utils.rb

Instance Method Summary collapse

Instance Method Details

#const_lookup(const, context = self) ⇒ Object

lookup a constant along the module nesting path



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
169
170
# File 'lib/doodle/utils.rb', line 142

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



34
35
36
# File 'lib/doodle/utils.rb', line 34

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)



39
40
41
# File 'lib/doodle/utils.rb', line 39

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

#doodle_callerObject

caller



118
119
120
121
122
123
124
# File 'lib/doodle/utils.rb', line 118

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



9
10
11
12
13
14
15
16
17
# File 'lib/doodle/utils.rb', line 9

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



137
138
139
# File 'lib/doodle/utils.rb', line 137

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



70
71
72
73
74
75
76
77
# File 'lib/doodle/utils.rb', line 70

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)



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

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



108
109
110
111
112
113
114
115
# File 'lib/doodle/utils.rb', line 108

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



21
22
23
24
25
26
27
28
# File 'lib/doodle/utils.rb', line 21

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



103
104
105
# File 'lib/doodle/utils.rb', line 103

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



96
97
98
# File 'lib/doodle/utils.rb', line 96

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



89
90
91
# File 'lib/doodle/utils.rb', line 89

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



82
83
84
# File 'lib/doodle/utils.rb', line 82

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



127
128
129
130
131
132
133
# File 'lib/doodle/utils.rb', line 127

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