Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Raise error if "initialize" method name is misspelled
# Public: Implementation of "Strike a match" algorithm for calculating
# similarity between strings.
#
# http://www.catalysoft.com/articles/StrikeAMatch.html
#
# Examples
#
# checker = StringSimilarityChecker.new('Quick brown fox')
#
# checker =~ 'quick brown ox' #=> true
# checker.similarity_index('quick brown ox') #=> 0.947
#
# checker =~ 'quick frown pox' #=> true
# checker.similarity_index('quick frown pox') #=> 0.8
#
# checker =~ 'quick lawn ducks' #=> false
# checker.similarity_index('quick lawn ducks') #=> 0.476
class StringSimilarityChecker
def initialize base_string, similarity_treshold = 0.8
@base_pairs = character_pairs base_string
@treshold = similarity_treshold
end
# Public: Check if similarity index with given string passes the treshold.
def similar_to? string
similarity_index(string) >= @treshold
end
alias =~ similar_to?
# Public: Calculate similarity index between given and base strings.
#
# Returns a Float between 0 and 1.
def similarity_index string
pairs = character_pairs string
shared = count_identical_pairs @base_pairs, pairs
(2 * shared).to_f / (@base_pairs.size + pairs.size)
end
SPACE = ' '
# Internal: Break string into pairs of adjacent characters, excluding ones
# that contain spaces.
def character_pairs str
str = str.to_str.downcase
(0..(str.size-2)).map {|pos| str[pos,2] }.reject {|pair| pair.include? SPACE }
end
# Internal: Measure the intersection between two arrays of character pairs.
def count_identical_pairs pairs1, pairs2
size, pairs2 = 0, pairs2.dup
pairs1.each do |pair|
if found = pairs2.index(pair)
size += 1
pairs2.delete_at found
end
end
size
end
end
class Class
initializer_name = 'initialize'
initializer_spelling_checker = StringSimilarityChecker.new initializer_name
# Raise error if a new method is similar but not identical to "initialize".
# WARNING this is not something you should actually use in your apps.
define_method(:method_added) do |name|
name = name.to_s
if name != initializer_name and initializer_spelling_checker =~ name
raise "method name too similar to 'initialize': '#{name}'"
end
end
end
class ThisWorks
def initialize # properly spelled method
end
def init # valid method name
end
end
class ThisFails
def initializer # wrong name
end
end
class ThisAlsoFails
def initilize # spelling error
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.