Class: String

Inherits:
Object show all
Defined in:
lib/quickbooks/structure.rb,
lib/qbxml/support.rb,
lib/quickbooks/ruby_magic.rb

Overview

This is serious super-magic code… :P Array and Hash are extended only slightly, with methods that will extend an Array object to be kept unique, or a Hash object to be kept in a given order or else in the order keys are defined; or an Array or Hash object just to retain the ordered-ness of contained hashes. ‘slashing’ in Array and Hash is the idea that multi-dimensional hashes and arrays could be represented by a key split by ‘/’s. In this way we can sort a multi-dimensional hash by a multi-dimensional array (to give the hash order), and then blow up the slash keys into actual multi-dimensional hashes.

Instance Method Summary collapse

Instance Method Details

#camelizeObject



45
46
47
# File 'lib/qbxml/support.rb', line 45

def camelize
  gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end

#constantizeObject



37
38
39
# File 'lib/qbxml/support.rb', line 37

def constantize
  Object.module_eval("::#{self}", __FILE__, __LINE__)
end

#expand_slashes(seed = nil, overwrite = false) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/quickbooks/structure.rb', line 15

def expand_slashes(seed=nil,overwrite=false)
  return self.dup if !slashed? && seed.nil?

  hsh = seed.nil? ? [] : (seed.is_a?(Array) ? seed : [seed])
  leaf = hsh
  slashed = self
  s = nil
  redoing = false
  while(slashed)
    s, slashed = slashed.split('/',2) unless redoing
    redoing = false

    # break when we can't go further

    # If leaf is a hash, continue into hash[s] if an array, or if a hash and !slashed.nil?.
    if leaf.is_a?(Hash)
      if leaf.has_key?(s)
        if leaf[s].is_a?(Array) || (leaf[s].is_a?(Hash) && slashed.to_s.split('/').length > 1)
          leaf = leaf[s]
        else
          break
        end
      else
        break
      end


    # If leaf is an array, continue only if !slashed.nil? AND an included hash contains the key
    elsif leaf.is_a?(Array)
      if !slashed.nil? && ((false) || h = leaf.reject {|e| !e.is_a?(Hash)}.reject {|e| !e.has_key?(s)}[-1])
        leaf = h
        redoing = true
        redo
      else
        break
      end
    end
  end

  # now we have leaf, which is where we need to append our value(s); s, the next segment, and slashed, which is all the rest of the segments
  if slashed
    case leaf
    when Hash
      if leaf.has_key?(s)
        if overwrite
          leaf[s] = slashed.expand_slashes
        else
          if leaf[s].is_a?(Array)
            leaf[s] = leaf[s] + slashed.expand_slashes
          else
            leaf[s] = [leaf[s], slashed.expand_slashes]
          end
        end
      else
        leaf[s] = slashed.expand_slashes
      end
    when Array
      if overwrite && leaf.include?(s)
        leaf[leaf.index(s)] = {s => slashed.expand_slashes}
      else
        if leaf[-1].is_a?(Hash)
          leaf[-1][s] = slashed.expand_slashes
        else
          leaf << {s => slashed.expand_slashes}
        end
      end
    end


  # There's no more, just the end value. leaf shouldn't be a hash in this case
  else
    case leaf
    when Hash
      # If leaf IS a hash, it must be the root hsh. In that case, it becomes obvious we need hsh to be an array, not a hash
      hsh = [hsh, s]
    when Array
      leaf << s unless overwrite && leaf.include?(s)
    end
  end

  hsh.length < 2 ? hsh[0] : hsh
end

#flatten_slashesObject



12
13
14
# File 'lib/quickbooks/structure.rb', line 12

def flatten_slashes
  self
end

#slashed?Boolean

Returns:

  • (Boolean)


9
10
11
# File 'lib/quickbooks/structure.rb', line 9

def slashed?
  self =~ /\//
end

#underscoreObject



41
42
43
# File 'lib/qbxml/support.rb', line 41

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