Предположим, вам нужно считать слова, а не символы, я полагаю, вы ожидаете, что класс будет называться:
WordCount.word_count_from_string('Words from this string of words')
или
WordCount.word_count_from_file('filename.txt')
Тогда вам нужно два метода класса, вызывающих другие методы, чтобы получить результат. Итак, это один из вариантов, чтобы заставить его работать:
class WordCount
def self.word_count_from_file(filename)
s = File.open(filename) { |file| file.read }
count_frequency(s)
end
def self.word_count_from_string(s)
count_frequency(s)
end
def self.words_array(s)
s.downcase.scan(/[\w']+/)
end
def self.count_frequency(s)
counts = Hash.new(0)
for character in words_array(s) # <-- there were a typo
counts[character] += 1
end
counts.to_a.sort do |a,b|
[b[1],a[0]] <=> [a[1],b[0]]
end
end
end
WordCount.word_count_from_string('Words from this string of words')
#=> [["words", 2], ["from", 1], ["of", 1], ["string", 1], ["this", 1]]
WordCount.word_count_from_file('word-count.txt')
#=> [["words", 2], ["this", 1], ["in", 1], ["of", 1], ["string", 1], ["a", 1], ["from", 1], ["file", 1]]
Обратите внимание, что и word_count_from_file
, и word_count_from_string
вызывают count_frequency
, что вызывает words_array
, чтобы получить и вернуть результат.
Чтобы иметь больше Ruby-ish (
each
) и меньше Pythonic (
for
), это альтернативная версия, использующая также переменную экземпляра (
@s
), чтобы избежать передачи параметров (
count_frequency
вместо
count_frequency(s)
, и др.).
class WordCount
def self.word_count_from_file(filename)
@s = File.open(filename) { |file| file.read }
count_frequency
end
def self.word_count_from_string(str)
@s = str
count_frequency
end
def self.count_frequency
words_array.each_with_object(Hash.new(0)) { |word, cnt| cnt[word] += 1 }.sort_by(&:last).reverse
end
def self.words_array
@s.downcase.scan(/[\w']+/)
end
end
Звоните как прежде.