Class: Ruby::Merge::MethodSimilarity

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby/merge/method_similarity.rb

Constant Summary collapse

DEFAULT_NAME_WEIGHT =
0.7
DEFAULT_PARAMS_WEIGHT =
0.3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name_weight: DEFAULT_NAME_WEIGHT, params_weight: DEFAULT_PARAMS_WEIGHT) ⇒ MethodSimilarity

Returns a new instance of MethodSimilarity.



11
12
13
14
# File 'lib/ruby/merge/method_similarity.rb', line 11

def initialize(name_weight: DEFAULT_NAME_WEIGHT, params_weight: DEFAULT_PARAMS_WEIGHT)
  @name_weight = name_weight
  @params_weight = params_weight
end

Instance Attribute Details

#name_weightObject (readonly)

Returns the value of attribute name_weight.



9
10
11
# File 'lib/ruby/merge/method_similarity.rb', line 9

def name_weight
  @name_weight
end

#params_weightObject (readonly)

Returns the value of attribute params_weight.



9
10
11
# File 'lib/ruby/merge/method_similarity.rb', line 9

def params_weight
  @params_weight
end

Instance Method Details

#call(template_name:, template_params:, dest_name:, dest_params:) ⇒ Object



16
17
18
19
20
21
# File 'lib/ruby/merge/method_similarity.rb', line 16

def call(template_name:, template_params:, dest_name:, dest_params:)
  name_score = string_similarity(template_name.to_s, dest_name.to_s)
  param_score = param_similarity(Array(template_params), Array(dest_params))

  (name_score * name_weight) + (param_score * params_weight)
end

#levenshtein_distance(str1, str2) ⇒ Object



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
# File 'lib/ruby/merge/method_similarity.rb', line 45

def levenshtein_distance(str1, str2)
  return str2.length if str1.empty?
  return str1.length if str2.empty?

  str1, str2 = str2, str1 if str1.length > str2.length

  m = str1.length
  n = str2.length
  previous_row = (0..m).to_a
  current_row = Array.new(m + 1, 0)

  (1..n).each do |j|
    current_row[0] = j

    (1..m).each do |i|
      cost = str1[i - 1] == str2[j - 1] ? 0 : 1
      current_row[i] = [
        previous_row[i] + 1,
        current_row[i - 1] + 1,
        previous_row[i - 1] + cost
      ].min
    end

    previous_row, current_row = current_row, previous_row
  end

  previous_row[m]
end

#param_similarity(template_params, dest_params) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ruby/merge/method_similarity.rb', line 23

def param_similarity(template_params, dest_params)
  return 1.0 if template_params.empty? && dest_params.empty?
  return 0.0 if template_params.empty? || dest_params.empty?

  common = (template_params & dest_params).size
  total = [template_params.size, dest_params.size].max
  count_ratio = [template_params.size, dest_params.size].min.to_f / total
  name_match_ratio = common.to_f / total

  (name_match_ratio * 0.7) + (count_ratio * 0.3)
end

#string_similarity(str1, str2) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/ruby/merge/method_similarity.rb', line 35

def string_similarity(str1, str2)
  return 1.0 if str1 == str2
  return 0.0 if str1.empty? || str2.empty?

  distance = levenshtein_distance(str1, str2)
  max_len = [str1.length, str2.length].max

  1.0 - (distance.to_f / max_len)
end