jaro_winkler 1.3.7 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7687918cbfcaa8ffb589f1d1383ac2e6611e235f
4
- data.tar.gz: e8129522a42193023a77593dddfe3917eafe3f68
3
+ metadata.gz: fe11a8c8be8cadef3f1f14f847c40a0a8e41268f
4
+ data.tar.gz: f509aaa81627917a4cf1017884f43b60dcd5483b
5
5
  SHA512:
6
- metadata.gz: be7befc2a7e5c5a2866ba7e4995bf99a0f9d75bfab3e01c806a1d39b10b0a27975f795f2330248e96e5673a8ce81d0ef01fa12a6d18f3f2cf73ff9de28764a60
7
- data.tar.gz: 3183fb3c534e1c1820ee16cd6a81bfcd35899ffc586e5ac064f5e4deace965d5507b83ca1d4a1fe3d8d30cc894da72eb998f1119ec3223a61c50c072d7e2029d
6
+ metadata.gz: 88fca6ab51c8a830de64e23b96f7efaaeeac01cd71735dd3820fc9e84e5de0027872014a8aef0278658d45455a7719a81601604929d17228fd6e8b6cb8fba919
7
+ data.tar.gz: ab7ee1020506ba6693e2b9878afddcb4a39bf7fb0be89b3958cfc5571f051b8295898cf050d517aa2c1951b23093517ce2d82d8d9c5544e816a4ac9e34c5bc6c
@@ -1,11 +1,11 @@
1
1
  unless RUBY_PLATFORM == 'java'
2
- require "mkmf"
2
+ require 'mkmf'
3
3
  $CFLAGS << ' -std=c99 '
4
- create_makefile("jaro_winkler/jaro_winkler")
4
+ create_makefile('jaro_winkler/jaro_winkler_ext')
5
5
  else
6
- dummy_makefile = open("Makefile", "wb")
6
+ dummy_makefile = open('Makefile', 'wb')
7
7
  dummy_makefile.puts '.PHONY: install'
8
8
  dummy_makefile.puts 'install:'
9
- dummy_makefile.puts "\t" + '@echo "Extensions not installed, falling back to pure Ruby version."'
9
+ dummy_makefile.puts "\t" + '@echo "C extension is not installed, fall back to pure Ruby version instead."'
10
10
  dummy_makefile.close
11
11
  end
@@ -6,19 +6,47 @@
6
6
  #include <stdlib.h>
7
7
  #include <ctype.h>
8
8
 
9
- double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str, int long_str_len, LibJaroOption *opt){
9
+ #define SWAP(x, y) do{ __typeof__(x) SWAP = x; x = y; y = SWAP; }while(0)
10
+
11
+ double jaro_distance_from_codes(unsigned long long *codes1, int len1, unsigned long long *codes2, int len2, LibJaroOption *opt);
12
+ double jaro_winkler_distance_from_codes(unsigned long long *codes1, int len1, unsigned long long *codes2, int len2, LibJaroOption *opt);
13
+
14
+ double jaro_distance(char* short_str, int short_str_len, char* long_str, int long_str_len, LibJaroOption *opt){
10
15
  if(!short_str_len || !long_str_len) return 0.0;
11
16
 
12
- if(short_str_len > long_str_len){
13
- SWAP(short_str, long_str);
14
- SWAP(short_str_len, long_str_len);
15
- }
17
+ unsigned long long *short_codes, *long_codes;
18
+ int short_codes_len, long_codes_len;
19
+ string_to_codes(short_str, short_str_len, &short_codes, &short_codes_len);
20
+ string_to_codes(long_str, long_str_len, &long_codes, &long_codes_len);
21
+
22
+ double ret = jaro_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
23
+
24
+ free(short_codes); free(long_codes);
25
+ return ret;
26
+ }
27
+
28
+ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str, int long_str_len, LibJaroOption *opt){
29
+ if(!short_str_len || !long_str_len) return 0.0;
16
30
 
17
31
  unsigned long long *short_codes, *long_codes;
18
32
  int short_codes_len, long_codes_len;
19
33
  string_to_codes(short_str, short_str_len, &short_codes, &short_codes_len);
20
34
  string_to_codes(long_str, long_str_len, &long_codes, &long_codes_len);
21
35
 
36
+ double ret = jaro_winkler_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
37
+
38
+ free(short_codes); free(long_codes);
39
+ return ret;
40
+ }
41
+
42
+ double jaro_distance_from_codes(unsigned long long* short_codes, int short_codes_len, unsigned long long* long_codes, int long_codes_len, LibJaroOption *opt){
43
+ if(!short_codes_len || !long_codes_len) return 0.0;
44
+
45
+ if(short_codes_len > long_codes_len){
46
+ SWAP(short_codes, long_codes);
47
+ SWAP(short_codes_len, long_codes_len);
48
+ }
49
+
22
50
  if(opt->ignore_case){
23
51
  for(int i = 0; i < short_codes_len; i++) short_codes[i] = tolower(short_codes[i]);
24
52
  for(int i = 0; i < long_codes_len; i++) long_codes[i] = tolower(long_codes[i]);
@@ -27,10 +55,10 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
27
55
  int window_size = long_codes_len/2 - 1;
28
56
  if(window_size < 0) window_size = 0;
29
57
 
30
- char short_codes_flag[short_str_len];
31
- char long_codes_flag[long_str_len];
32
- memset(short_codes_flag, 0, short_str_len);
33
- memset(long_codes_flag, 0, long_str_len);
58
+ char short_codes_flag[short_codes_len];
59
+ char long_codes_flag[long_codes_len];
60
+ memset(short_codes_flag, 0, short_codes_len);
61
+ memset(long_codes_flag, 0, long_codes_len);
34
62
 
35
63
  // count number of matching characters
36
64
  int match_count = 0;
@@ -46,10 +74,8 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
46
74
  }
47
75
  }
48
76
  }
49
- if(!match_count){
50
- free(short_codes); free(long_codes);
51
- return 0.0;
52
- }
77
+
78
+ if(!match_count) return 0.0;
53
79
 
54
80
  // count number of transpositions
55
81
  int transposition_count = 0, j = 0, k = 0;
@@ -77,27 +103,20 @@ double jaro_winkler_distance(char* short_str, int short_str_len, char* long_str,
77
103
  break;
78
104
  }
79
105
 
80
- // jaro distance
81
- double jaro_distance;
82
106
  double m = (double)match_count;
83
107
  double t = (double)(transposition_count/2);
84
108
  if(opt->adj_table) m = similar_count/10.0 + m;
85
- jaro_distance = (m/short_codes_len + m/long_codes_len + (m-t)/m) / 3;
109
+ return (m/short_codes_len + m/long_codes_len + (m-t)/m) / 3;
110
+ }
86
111
 
87
- // jaro winkler distance
88
- if(!opt){
89
- static LibJaroOption default_opt = {.weight = DEFAULT_WEIGHT, .threshold = DEFAULT_THRESHOLD};
90
- opt = &default_opt;
91
- }
92
- if(jaro_distance < opt->threshold){
93
- free(short_codes); free(long_codes);
94
- return jaro_distance;
95
- }
112
+ double jaro_winkler_distance_from_codes(unsigned long long* short_codes, int short_codes_len, unsigned long long* long_codes, int long_codes_len, LibJaroOption *opt){
113
+ double jaro_distance = jaro_distance_from_codes(short_codes, short_codes_len, long_codes, long_codes_len, opt);
114
+
115
+ if(jaro_distance < opt->threshold) return jaro_distance;
96
116
  else{
97
117
  int prefix = 0;
98
118
  int max_4 = short_codes_len > 4 ? 4 : short_codes_len;
99
119
  for(prefix = 0; prefix < max_4 && short_codes[prefix] == long_codes[prefix]; prefix++);
100
- free(short_codes); free(long_codes);
101
120
  return jaro_distance + prefix*opt->weight*(1-jaro_distance);
102
121
  }
103
122
  }
@@ -1,7 +1,6 @@
1
1
  #ifndef LIBJARO_JARO_H
2
2
  #define LIBJARO_JARO_H
3
3
 
4
- #define SWAP(x, y) do{ __typeof__(x) SWAP = x; x = y; y = SWAP; }while(0)
5
4
  #define DEFAULT_WEIGHT 0.1
6
5
  #define DEFAULT_THRESHOLD 0.7
7
6
 
@@ -10,6 +9,9 @@ typedef struct LibJaroOption{
10
9
  char ignore_case, adj_table;
11
10
  } LibJaroOption;
12
11
 
12
+
13
+ static const LibJaroOption DEFAULT_OPT = {.weight = DEFAULT_WEIGHT, .threshold = DEFAULT_THRESHOLD, .ignore_case = 0, .adj_table = 0};
14
+ double jaro_distance(char *str1, int len1, char *str2, int len2, LibJaroOption *opt);
13
15
  double jaro_winkler_distance(char *str1, int len1, char *str2, int len2, LibJaroOption *opt);
14
16
 
15
17
  #endif
@@ -1,28 +1,45 @@
1
1
  #include "ruby.h"
2
2
  #include "jaro.h"
3
3
 
4
- VALUE rb_mJaroWinkler;
5
- VALUE distance(int argc, VALUE *argv, VALUE self);
4
+ VALUE rb_mJaroWinkler,
5
+ rb_eError,
6
+ rb_eInvalidWeightError;
6
7
 
7
- void Init_jaro_winkler(void){
8
+ VALUE rb_jaro_winkler_distance(int argc, VALUE *argv, VALUE self);
9
+ VALUE rb_jaro_distance(int argc, VALUE *argv, VALUE self);
10
+ VALUE distance(int argc, VALUE *argv, VALUE self, double (*distance_fn)(char *str1, int len1, char *str2, int len2, LibJaroOption *opt));
11
+
12
+ void Init_jaro_winkler_ext(void){
8
13
  rb_mJaroWinkler = rb_define_module("JaroWinkler");
9
- rb_define_module_function(rb_mJaroWinkler, "c_distance", distance, -1);
14
+ rb_eError = rb_define_class_under(rb_mJaroWinkler, "Error", rb_eRuntimeError);
15
+ rb_eInvalidWeightError = rb_define_class_under(rb_mJaroWinkler, "InvalidWeightError", rb_eError);
16
+ rb_define_module_function(rb_mJaroWinkler, "distance", rb_jaro_winkler_distance, -1);
17
+ rb_define_module_function(rb_mJaroWinkler, "jaro_distance", rb_jaro_distance, -1);
10
18
  }
11
19
 
12
- VALUE distance(int argc, VALUE *argv, VALUE self){
20
+
21
+ VALUE distance(int argc, VALUE *argv, VALUE self, double (*distance_fn)(char *str1, int len1, char *str2, int len2, LibJaroOption *opt)){
13
22
  VALUE s1, s2, opt;
14
23
  rb_scan_args(argc, argv, "2:", &s1, &s2, &opt);
15
- LibJaroOption c_opt = {.weight = DEFAULT_WEIGHT, .threshold = DEFAULT_THRESHOLD, .ignore_case = 0, .adj_table = 0};
24
+ LibJaroOption c_opt = DEFAULT_OPT;
16
25
  if(TYPE(opt) == T_HASH){
17
26
  VALUE weight = rb_hash_aref(opt, ID2SYM(rb_intern("weight"))),
18
27
  threshold = rb_hash_aref(opt, ID2SYM(rb_intern("threshold"))),
19
28
  ignore_case = rb_hash_aref(opt, ID2SYM(rb_intern("ignore_case"))),
20
29
  adj_table = rb_hash_aref(opt, ID2SYM(rb_intern("adj_table")));
21
30
  if(!NIL_P(weight)) c_opt.weight = NUM2DBL(weight);
22
- if(c_opt.weight > 0.25) rb_raise(rb_eRuntimeError, "Scaling factor should not exceed 0.25, otherwise the distance can become larger than 1.");
31
+ if(c_opt.weight > 0.25) rb_raise(rb_eInvalidWeightError, "Scaling factor should not exceed 0.25, otherwise the distance can become larger than 1.");
23
32
  if(!NIL_P(threshold)) c_opt.threshold = NUM2DBL(threshold);
24
33
  if(!NIL_P(ignore_case)) c_opt.ignore_case = (TYPE(ignore_case) == T_FALSE || NIL_P(ignore_case)) ? 0 : 1;
25
34
  if(!NIL_P(adj_table)) c_opt.adj_table = (TYPE(adj_table) == T_FALSE || NIL_P(adj_table)) ? 0 : 1;
26
35
  }
27
- return rb_float_new(jaro_winkler_distance(StringValuePtr(s1), RSTRING_LEN(s1), StringValuePtr(s2), RSTRING_LEN(s2), &c_opt));
36
+ return rb_float_new((*distance_fn)(StringValuePtr(s1), RSTRING_LEN(s1), StringValuePtr(s2), RSTRING_LEN(s2), &c_opt));
37
+ }
38
+
39
+ VALUE rb_jaro_distance(int argc, VALUE *argv, VALUE self){
40
+ return distance(argc, argv, self, jaro_distance);
41
+ }
42
+
43
+ VALUE rb_jaro_winkler_distance(int argc, VALUE *argv, VALUE self){
44
+ return distance(argc, argv, self, jaro_winkler_distance);
28
45
  }
@@ -1,76 +1,9 @@
1
- require 'jaro_winkler/fallback'
2
- require 'jaro_winkler/adjusting_table'
3
- require 'jaro_winkler/jaro_winkler.so' unless JaroWinkler.fallback?
4
- module JaroWinkler
5
- module_function
6
- def jaro_distance s1, s2, options = {}
7
- options[:adj_table]
8
- length1, length2 = s1.length, s2.length
9
- # Guarantee the length order
10
- if s1.length > s2.length
11
- s1, s2 = s2, s1
12
- length1, length2 = length2, length1
13
- end
14
- window_size = (length2 / 2) - 1
15
- window_size = 0 if window_size < 0
16
- matches = 0.0
17
- sim_matches = 0.0
18
- transpositions = 0
19
- previous_index = -1
20
- max_index = length2 - 1
21
- s1.chars.each_with_index do |c1, i|
22
- left = i - window_size
23
- right = i + window_size
24
- left = 0 if left < 0
25
- right = max_index if right > max_index
26
- matched = false
27
- sim_matched = false
28
- found = false
29
- s2[left..right].chars.each_with_index do |c2, j|
30
- if c1 == c2
31
- matched = true
32
- s2_index = left + j
33
- if !found && s2_index > previous_index
34
- previous_index = s2_index
35
- found = true
36
- end
37
- elsif options[:adj_table] && DEFAULT_ADJ_TABLE[c1][c2]
38
- sim_matched = true
39
- end
40
- end
41
- if matched
42
- matches += 1
43
- transpositions += 1 unless found
44
- elsif sim_matched # not matched but similarly matched
45
- sim_matches += 3
46
- end
47
- end
48
- # Don't divide transpositions by 2 since it's been counted directly by above code.
49
- similarity = matches
50
- similarity += sim_matches / 10 if options[:adj_table]
51
- matches == 0 ? 0 : (similarity / length1 + similarity / length2 + (matches - transpositions) / matches) / 3.0
52
- end
1
+ require 'jaro_winkler/version'
53
2
 
54
- def r_distance s1, s2, options = {}
55
- options = {weight: 0.1, threshold: 0.7, ignore_case: false, adj_table: false}.merge options
56
- weight, threshold, ignore_case = options[:weight], options[:threshold], options[:ignore_case]
57
- raise 'Scaling factor should not exceed 0.25, otherwise the distance can become larger than 1' if weight > 0.25
58
- s1, s2 = s1.upcase, s2.upcase if ignore_case
59
- distance = jaro_distance(s1, s2, options)
60
- prefix = 0
61
- max_length = [4, s1.length, s2.length].min
62
- s1[0, max_length].chars.each_with_index do |c1, i|
63
- c1 == s2[i] ? prefix += 1 : break
64
- end
65
- distance < threshold ? distance : distance + ((prefix * weight) * (1 - distance))
66
- end
67
-
68
- if JaroWinkler.fallback?
69
- alias :distance :r_distance
70
- alias :c_distance :r_distance
71
- module_function :distance, :c_distance
72
- else
73
- alias :distance :c_distance
74
- module_function :distance
75
- end
76
- end
3
+ case RUBY_PLATFORM
4
+ when 'java'
5
+ require 'jaro_winkler/jaro_winkler_pure'
6
+ else
7
+ require 'jaro_winkler/jaro_winkler_ext'
8
+ end
9
+
@@ -0,0 +1,125 @@
1
+ require 'jaro_winkler/adjusting_table'
2
+ module JaroWinkler
3
+ class Error < RuntimeError; end
4
+ class InvalidWeightError < Error; end
5
+
6
+ DEFAULT_WEIGHT = 0.1
7
+ DEFAULT_THRESHOLD = 0.7
8
+ DEFAULT_OPTIONS = {
9
+ jaro: {adj_table: false, ignore_case: false},
10
+ jaro_winkler: {weight: DEFAULT_WEIGHT, threshold: DEFAULT_THRESHOLD}
11
+ }
12
+
13
+ module_function
14
+
15
+ def distance str1, str2, options={}
16
+ _distance str1.codepoints.to_a, str2.codepoints.to_a, options
17
+ end
18
+
19
+ def jaro_distance str1, str2, options={}
20
+ _jaro_distance str1.codepoints.to_a, str2.codepoints.to_a, options
21
+ end
22
+
23
+ def _distance codes1, codes2, options={}
24
+ options = DEFAULT_OPTIONS[:jaro_winkler].merge options
25
+ raise InvalidWeightError if options[:weight] > 0.25
26
+ jaro_distance = _jaro_distance(codes1, codes2, options);
27
+
28
+ if jaro_distance < options[:threshold]
29
+ jaro_distance
30
+ else
31
+ codes1, codes2 = codes2, codes1 if codes1.length > codes2.length
32
+ len1, len2 = codes1.length, codes2.length
33
+ max_4 = len1 > 4 ? 4 : len1
34
+ prefix = 0
35
+ while prefix < max_4 && codes1[prefix] == codes2[prefix]
36
+ prefix += 1
37
+ end
38
+ jaro_distance + prefix * options[:weight] * (1 - jaro_distance)
39
+ end
40
+ end
41
+
42
+ def _jaro_distance codes1, codes2, options={}
43
+ options = DEFAULT_OPTIONS[:jaro].merge options
44
+
45
+ codes1, codes2 = codes2, codes1 if codes1.length > codes2.length
46
+ len1, len2 = codes1.length, codes2.length
47
+ return 0.0 if len1 == 0 || len2 == 0
48
+
49
+ if options[:ignore_case]
50
+ codes1.map!{ |c| c >= 97 && c <= 122 ? c -= 32 : c }
51
+ codes2.map!{ |c| c >= 97 && c <= 122 ? c -= 32 : c }
52
+ end
53
+
54
+ window = len2/2 - 1
55
+ window = 0 if(window < 0)
56
+ flags1, flags2 = 0, 0
57
+
58
+ # // count number of matching characters
59
+ match_count = 0;
60
+ i = 0
61
+ while i < len1
62
+ left = (i >= window) ? i - window : 0
63
+ right = (i + window <= len2 - 1) ? (i + window) : (len2 - 1)
64
+ right = len2 - 1 if right > len2 - 1
65
+ j = left
66
+ while j <= right
67
+ if flags2[j] == 0 && codes1[i] == codes2[j]
68
+ flags1 |= (1 << i)
69
+ flags2 |= (1 << j)
70
+ match_count += 1
71
+ break
72
+ end
73
+ j +=1
74
+ end
75
+ i += 1
76
+ end
77
+
78
+ return 0.0 if match_count == 0
79
+
80
+ # // count number of transpositions
81
+ transposition_count = j = k = 0
82
+ i = 0
83
+ while i < len1
84
+ if flags1[i] == 1
85
+ j = k
86
+ while j < len2
87
+ if flags2[j] == 1
88
+ k = j + 1;
89
+ break;
90
+ end
91
+ j += 1
92
+ end
93
+ transposition_count += 1 if codes1[i] != codes2[j]
94
+ end
95
+ i += 1
96
+ end
97
+
98
+ # // count similarities in nonmatched characters
99
+ similar_count = 0
100
+ if options[:adj_table] && len1 > match_count
101
+ i = 0
102
+ while i < len1
103
+ if flags1[i] == 0
104
+ j = 0
105
+ while j < len2
106
+ if flags2[j] == 0
107
+ if DEFAULT_ADJ_TABLE[codes1[i].chr(Encoding::UTF_8)][codes2[j].chr(Encoding::UTF_8)]
108
+ similar_count += 3
109
+ break
110
+ end
111
+ end
112
+ j += 1
113
+ end
114
+ end
115
+ i += 1
116
+ end
117
+ end
118
+
119
+ m = match_count.to_f
120
+ t = transposition_count/2
121
+ m = similar_count/10.0 + m if options[:adj_table]
122
+ (m/len1 + m/len2 + (m-t)/m) / 3
123
+ end
124
+
125
+ end
@@ -1,3 +1,3 @@
1
1
  module JaroWinkler
2
- VERSION = "1.3.7"
2
+ VERSION = '1.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jaro_winkler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.7
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jian Weihang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-28 00:00:00.000000000 Z
11
+ date: 2015-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,49 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: fuzzy-string-match
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: hotwater
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: amatch
56
+ name: minitest
99
57
  requirement: !ruby/object:Gem::Requirement
100
58
  requirements:
101
59
  - - ">="
@@ -128,7 +86,7 @@ files:
128
86
  - ext/jaro_winkler/murmur_hash2.c
129
87
  - lib/jaro_winkler.rb
130
88
  - lib/jaro_winkler/adjusting_table.rb
131
- - lib/jaro_winkler/fallback.rb
89
+ - lib/jaro_winkler/jaro_winkler_pure.rb
132
90
  - lib/jaro_winkler/version.rb
133
91
  homepage: https://github.com/tonytonyjan/jaro_winkler
134
92
  licenses:
@@ -150,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
108
  version: '0'
151
109
  requirements: []
152
110
  rubyforge_project:
153
- rubygems_version: 2.4.5.1
111
+ rubygems_version: 2.5.1
154
112
  signing_key:
155
113
  specification_version: 4
156
114
  summary: Ruby & C implementation of Jaro-Winkler distance algorithm which both support
@@ -1,6 +0,0 @@
1
- module JaroWinkler
2
- module_function
3
- def fallback?
4
- RUBY_PLATFORM == 'java'
5
- end
6
- end