Поросячья Латынь Переводчик


Может кто-то проверить следующий код?

class PigLatin

  attr_accessor :phrase
  ending = "ay"

  def initialize the_phrase
    @phrase = the_phrase
  end

  def translate
    translated_phrase = String.new
    words = @phrase.split
    words.each do |word|
      puts word
      if vowel_is_first word
        translated_phrase +=  translate_with_vowel(word)
      else
        translated_phrase += translate_with_consonant(word)
      end
    end

    clean_up translated_phrase
  end

  def vowel_is_first test_word
    true if test_word[0] =~ /aeiou/ #will this make false since 0??
    false
  end

  def translate_with_vowel word
    word + "-" + ending + " "
  end

  def translate_with_consonant word
    return word + "-way " if word.size <= 2
    split_location = word =~ /a|e|i|o|u/
    word_array_length = word.size - 1

    first_segment = word[split_location,word_array_length]
    second_segment = "-" + word[0,split_location-1] + word[split_location-1]  + "ay" + " "

    first_segment + second_segment
  end

  def clean_up to_be_cleaned
    to_be_cleaned = to_be_cleaned[0..to_be_cleaned.size-2]
    to_be_cleaned.capitalize
  end
end

Я уверен, что это могло использовать некоторую работу, а я просто иду в Ruby, поэтому ничего и все было бы полезно. Функция очистки, я думаю, может специально работать. Он получает работу, но без нее всегда есть место в конце, и НТР.прокладки не получал работу.



1563
7
задан 6 мая 2011 в 05:05 Источник Поделиться
Комментарии
1 ответ

Прежде всего, есть две ошибки в коде:


  1. окончание = "ай" - это локальная переменная видима только непосредственно в теле класса, а не внутри деф- ов. По этой причине translate_with_vowel будут бросать NameError, когда он вызывается. Вы должны сделать его постоянным, так что он будет виден везде.

  2. Причина того, что вы не заметили, первая ошибка заключается в том, что translate_with_vowel никогда не вызывается, потому что vowel_is_first будет всегда возвращать значение false. Вы должны использовать , если ... иначе ... конец вместо встроенного , если. Причина того, что он не работает так, как ты написал, что с правдой если test_word[0] =~ /aeiou/ не последнее выражение в методе, поэтому его возвращаемое значение просто выбрасывается и он не имеет каких-либо побочных эффектов.


С точки зрения дизайна, я немного сомнительно, что имея PigLatin объекта для каждой строки, которую вы хотите перевести очень хорошая идея. Каждый PigLatin объект имеет один экземпляр переменной, которая устанавливается в инициализации и используется ровно один способ (перевод). Все остальные способы зависят только от своих аргументов, а не на состояние объекта. Так что с программистской точки зрения, имея строку, инкапсулированных в объект, покупает вам ничего более принимать это как аргумент, чтобы перевести.

С точки зрения она также делает API более громоздким, чем он должен быть. Нет никаких причин предпочитать PigLatin.новый(строку).перевести за PigLatin.перевод(строка) если нет никаких причин, почему я когда-либо использовать более одного метода на объект, там действительно нет причин для объекта существовать вообще.

Если перевод был параметризуются некоторые параметры конфигурации, это имело бы смысл, чтобы иметь класс, который инстанцируют с нужным и перевести метод, который принимает строку, как это:

pig_latin = Translator.new(:input => :english, :output => :pig_latin)
string1 = pig_latin.translate("Hello World")
string2 = pig_latin.translate("Goodbye World")

Однако поскольку в данном случае нет никаких вариантов, я бы рекомендовал использовать PigLatin модуль и определения всех методов, как module_functionС. Таким образом, использование будет PigLatin.перевести("Привет мир") или включить PigLatin; переводить("Здравствуй, Мир").

Кроме того, поскольку нет никаких причин, почему пользователь должен либо вызвать любой из методов, за исключением перевода, другие методы, вероятно, должен быть отдельный.


  def translate
translated_phrase = String.new
words = @phrase.split
words.each do |word|
puts word
if vowel_is_first word
translated_phrase += translate_with_vowel(word)
else
translated_phrase += translate_with_consonant(word)
end
end

clean_up translated_phrase
end

Я предполагаю, что ставит просто старый отладки заявление, вы забыли снять. Если нет, посоветуйте, что смешивание Ио с логикой обычно плохой дизайн. Если это так, маленький совет: Если вы используете п , а не ставит для отладочных операторов, вы получите вывод, который является более полезным, потому что вы можете увидеть, является ли объект имеет тип вы ожидаете, и, в случае строк, содержит ли он каких-либо непечатных мета-символов.

Строку.новым является только более многословный способ сказать "", так что вы должны использовать это вместо этого. Однако, вместо того чтобы добавить пустую строку в каждый цикл, я бы предпочел использовать карту и присоединиться. Присоединяйтесь также позаботиться вставки пробелов между элементами для вас (если вы скажете ей, то есть), так что вам не нужно, чтобы добавить эти места себе в translate_ методами и вы не должны удалить пробел в конце.

Так что я бы написал перевод такой:

 def translate(string)
words = @phrase.split
translated_words = words.map do |word|
if vowel_is_first word
translate_with_vowel(word)
else
translate_with_consonant(word)
end
end
translated_phrase = translated_words.join(" ")
translated_phrase.capitalize
end

Вы можете также определить еще один вспомогательный метод translate_word в котором содержится выше , если заявление, а затем упростить выше translated_words = слова.карта(&:translate_word).


  def translate_with_consonant word
return word + "-way " if word.size <= 2
split_location = word =~ /a|e|i|o|u/
word_array_length = word.size - 1

first_segment = word[split_location,word_array_length]
second_segment = "-" + word[0,split_location-1] + word[split_location-1] + "ay" + " "

first_segment + second_segment
end

Весь split_location очень сложный. Просто использовать строку#сплит (который принимает целое число в качестве второго аргумента, который вы можете использовать, чтобы сказать ему, что вы только хотите разделить строку на две части). Вы также можете использовать строку интерполяции вместо конкатенации. И как я уже сказал, Вы можете избавиться от В + " " А вот теперь обрабатывается присоединиться.

Я бы написал это так:

  def translate_with_consonant word
return word + "-way " if word.size <= 2
second_segment, first_segement = word.split(/a|e|i|o|u/, 2)

"#{ first_segment }-#{ second_segment }ay"
end

8
ответ дан 6 мая 2011 в 07:05 Источник Поделиться