Class: String

Inherits:
Object show all
Defined in:
lib/strokedb/core_ext/blank.rb,
lib/strokedb/util/inflect.rb,
lib/strokedb/core_ext/string.rb,
lib/strokedb/sync/diff/string.rb
more...

Overview

extracted and adapted from ActiveRecord (rubyforge.org/projects/activesupport/)

Direct Known Subclasses

StrokeDB::DocumentReferenceValue

Instance Method Summary collapse

Instance Method Details

#/(o) ⇒ Object

[View source]

43
44
45
# File 'lib/strokedb/core_ext/string.rb', line 43

def /(o)
  File.join(self, o.to_s)
end

#blank?Boolean

Returns:

  • (Boolean)
[View source]

41
42
43
# File 'lib/strokedb/core_ext/blank.rb', line 41

def blank?
  self !~ /\S/
end

#camel_caseObject Also known as: camelize

[View source]

9
10
11
# File 'lib/strokedb/core_ext/string.rb', line 9

def camel_case
  split('_').map{|e| e.capitalize}.join
end

#constantizeObject

[View source]

33
34
35
36
37
38
39
40
41
# File 'lib/strokedb/core_ext/string.rb', line 33

def constantize
  if /^meta:/ =~ self
    return StrokeDB::META_CACHE[Meta.make_uuid_from_fullname(self)]
  end
  unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
    raise NameError, "#{self.inspect} is not a valid constant name!"
  end
  Object.module_eval("::#{$1}", __FILE__, __LINE__)
end

#demodulizeObject

[View source]

24
25
26
# File 'lib/strokedb/core_ext/string.rb', line 24

def demodulize
  gsub(/^.*::/, '')
end

#ends_with?(suffix) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

4
5
6
7
# File 'lib/strokedb/core_ext/string.rb', line 4

def ends_with?(suffix)
  suffix = suffix.to_s
  self[-suffix.length, suffix.length] == suffix
end

#linesObject

[View source]

59
60
61
# File 'lib/strokedb/core_ext/string.rb', line 59

def lines
  self.split("\n").size
end

#modulizeObject

[View source]

28
29
30
31
# File 'lib/strokedb/core_ext/string.rb', line 28

def modulize
  return '' unless include?('::') && self[0,2] != '::'
  self.gsub(/^(.+)::(#{demodulize})$/,'\\1')
end

#pluralObject Also known as: pluralize

[View source]

213
214
215
# File 'lib/strokedb/util/inflect.rb', line 213

def plural
  English::Inflect.plural(self)
end

#singularObject Also known as: singularize

[View source]

208
209
210
# File 'lib/strokedb/util/inflect.rb', line 208

def singular
  English::Inflect.singular(self)
end

#snake_caseObject

[View source]

14
15
16
# File 'lib/strokedb/core_ext/string.rb', line 14

def snake_case
  gsub(/\B[A-Z][^A-Z]/, '_\&').downcase.gsub(' ', '_')
end

#stroke_diff(to) ⇒ Object

[View source]

3
4
5
6
7
8
9
10
11
12
13
14
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
# File 'lib/strokedb/sync/diff/string.rb', line 3

def stroke_diff(to)
  return super(to) unless to.is_a?(String)
  return nil if self == to
  
  _f = self[0,2]
  _t = to[0,2]
  pfx = "@#"
  # both are refs
  return super(to) if _f == _t && _t == pfx
  # one of items is ref, another is not.
  return super(to) if _f == pfx || _t == pfx
        
  lcs_diff = ::Diff::LCS.diff(self, to)
  patchset = lcs_diff.map do |changes| 
    parts = []
    last_part = changes.inject(nil) do |part, change|
      if part && part[0] == change.action && part[3] == change.position - 1
        part[3] += 1
        part[2] << change.element
        part
      else
        parts << part if part
        # emit
        [change.action, change.position, change.element, change.position]
      end
    end
    parts << last_part if last_part
    parts.empty? ? nil : parts
  end.compact.inject([]) do |patches, ps|
    ps.map do |p|
      patches << if p[0] == '+'
        [PATCH_PLUS,  p[1], p[2]]      # [+  position_in_b  substr]
      else
        [PATCH_MINUS, p[1], p[2].size] # [-  position_in_a  length]
      end
    end
    patches
  end
  #p patchset
  patchset.empty? ? nil : patchset
end

#stroke_merge(patch1, patch2) ⇒ Object

[View source]

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/strokedb/sync/diff/string.rb', line 81

def stroke_merge(patch1, patch2)
  # One patch is missing (i.e. no changes)
  unless patch1 && patch2
    return _stroke_automerged(stroke_patch(patch1 || patch2))
  end

  # Patch could be either PATCH_REPLACE or regular string diff.
  # Thus, 4 cases:
  #
  # [replace, replace] -> possible conflict
  # [replace, diff]    -> conflict
  # [diff,    replace] -> conflict
  # [diff,    diff]    -> possible conflict

  # Code is verbose to be fast and clear
  if patch1[0] == PATCH_REPLACE
    if patch2[0] == PATCH_REPLACE # [replace, replace]
      if patch1[1] != patch2[1]
        return _stroke_conflicted(stroke_patch(patch1), stroke_patch(patch2))
      else
        return _stroke_automerged(stroke_patch(patch1))
      end
    else # [replace, diff]
       return _stroke_conflicted(stroke_patch(patch1), stroke_patch(patch2))
    end
  else
    if patch1[0] == PATCH_REPLACE # [diff, replace]
      return _stroke_conflicted(stroke_patch(patch1), stroke_patch(patch2))
    else
      nil # [diff, diff] - see below
    end
  end
	  # TODO: ...
end

#stroke_patch(patch) ⇒ Object

[View source]

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
# File 'lib/strokedb/sync/diff/string.rb', line 45

def stroke_patch(patch)
  return self unless patch
  return patch[1] if patch[0] == PATCH_REPLACE
  
  # Patch is a list of insertions and deletions.
  # Deletion is indexed relative to base.
  # Insertion is indexed relative to new string.
  res = ""
  ai = bj = 0
  patch.each do |change|
    action, position, element = change
    case action
    when PATCH_MINUS
      d = position - ai
      if d > 0
        res << self[ai, d]
        ai += d
        bj += d
      end
      ai += element # element == length
    when PATCH_PLUS
      d = position - bj
      if d > 0
        res << self[ai, d]
        ai += d
        bj += d
      end
      bj += element.size
      res << element
    end
  end
  d = self.size - ai
  res << self[ai, d] if d > 0
  res
end

#tableizeObject

[View source]

18
19
20
21
22
# File 'lib/strokedb/core_ext/string.rb', line 18

def tableize
  words = snake_case.split('_')
  words.last.replace words.last.plural
  words.join('_')
end

#underscoreObject

[View source]

51
52
53
54
55
56
57
# File 'lib/strokedb/core_ext/string.rb', line 51

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

#unindent!Object

[View source]

47
48
49
# File 'lib/strokedb/core_ext/string.rb', line 47

def unindent!
  self.gsub!(/^\n/, '').gsub!(/^#{self.match(/^\s*/)[0]}/, '')
end