2011-04-05 2 views
0

Я пытаюсь вернуть этот код при вызове без блока. Несовершенные строки внизу - это то, что я пытаюсь вернуть. Первая раскованная строка должна вернуться в тут, вторая строка переводится на английский, а последняя должна быть на английском языке. И почему линия «puts eng» возвращается вверх и вниз, а не в форме предложения? Спасибо за любую помощь.Ruby: Возврат метода без блока

Вот мой код:

class Tut 
     @@consonants = ["b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"] 

    def is_tut? string 
    if string =~ /^(([b-df-hj-np-z]ut)|([aeiou\s])|[[:punct:]])+$/i 
     yield 
    else 
     false 
    end 
    end 

    def self.to_tut string 
    string.each_char do |c| 
     c += "ut" if @@consonants.find { |i| i == c.downcase } 
     yield c if block_given? 
     end 
    end 

    def self.to_english string 
    array = string.split // 
    array.each do |c| 
     if @@consonants.find { |i| i == c.downcase } 
     array.shift 
     array.shift 
     end 
     yield c if block_given? 
    end 
    end 
end 

#Tut.to_tut("Wow! Look at this get converted to Tut!") { |c| print c } 
# should output : Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut! 

#puts 
#puts 

tut = Tut.to_tut("Wow! Look at this get converted to Tut!") 
puts "from return: #{tut}" 

puts 

#Tut.to_tut("Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!") { |c| print c } 
#should outout : Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut! 
#puts 
#puts 

tut = Tut.to_tut("Wutowut! Lutookut atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut!") 
puts "from return: #{tut}" 

#puts 

#tut_string = "" 
#Tut.to_tut("I'm in tut but I want to be in english.") { |c| tut_string += c } 
#puts tut_string 
# should output : I'mut inut tututut bututut I wutanuttut tuto bute inut enutgutlutisuthut. 

puts 

#Tut.to_english(tut_string){ |c| print c } 
# should output : I'm in tut but I want to be in english. 

lan = Tut.to_english(tut) 
puts lan 
+0

Uncommented lines? Неясно, о каких из них вы говорите. И вы имеете в виду прокомментированные, а не раскованные? – sawa

+0

Эти строки: репетит = Tut.to_tut ("Wow Посмотрите на это преобразуются в Тута!") путы "от возвращения: # {} TUT"! репетит = Tut.to_tut («Wutowut Lutookut Atut tuthutisut gutetut cutonutvuteruttutedut tuto Tututut! ") puts" from return: # {tut} " lan = Tut.to_english (tut) puts lan –

+0

Хорошо, я понял. «Некоммерческие строки» могут быть более понятными. «Uncommented» означает, что вы (активно) что-то сделали (например, отметили что-то) в строке с комментариями, чтобы сделать ее раскомментированной. – sawa

ответ

0

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

Ваш to_tut не сохраняет ваш поскольку блок-переменная «c» является копией строкового фрагмента, а не ссылкой на часть строки (если бы она была ссылкой, вы могли бы использовать < < для добавления; «+ =» все еще 't работать, потому что он переназначает, а не меняет ref). Вот как работает each_char, поскольку String не содержит ссылок.

Если вы хотите изменить строку на месте, вам, вероятно, придется рассчитывать назад, а затем вставлять «ut» по индексу через строку # [] =. Но это сложно, поэтому я представлю пару альтернатив.

Работа to_tut # 1:

def self.to_tut string 
    string.chars.map do |c| 
    yield c if block_given? 
    # this must be the last expression the block 
    if @@consonants.find { |i| i == c.downcase } 
     c + 'ut' 
    else 
     c 
    end 
    end.join 
end 

Работа to_tut # 2 - это, вероятно, самый рубин-иш способ сделать это:

def self.to_tut string 
    string.gsub(/[#{@@consonants.join}]/i) {|match| 
    yield match if block_given? 
    # this must be the last expression in the block 
    match + 'ut' 
    } 
end 

Ваш to_english не работает, так как массив. shift всегда удаляет первый элемент массива. Вместо этого вы хотите отслеживать текущий индекс и удалять 2 символа, начиная с индекса + 1.

Работа to_english:

def self.to_english2 string 
    array = string.split // 
    array.each_with_index do |c, idx| 
    if @@consonants.find { |i| i == c.downcase } 
     array.slice!(idx+1, 2) 
    end 
    yield c if block_given? 
    end 
    array.join 
end 

Относительно того, почему ваш «ставит участ» возвращает один символ в каждой строке - это потому, что ваш to_english возвращает массив. Вы захотите вызвать соединение, чтобы преобразовать его.

+0

Спасибо! Я не думал использовать соединение. Теперь все это имеет смысл. Спасибо за помощь. –

0

Методы to_tut и to_english дают вам неправильные ответы при использовании без блока. Это происходит потому, что ruby ​​всегда возвращает последнее значение, полученное в вашем методе. В вашем коде, который будет являться результатом string.each_char для to_tut или array.each для to_english. В обоих случаях результат содержит исходный ввод, который, следовательно, возвращается и печатается.

Что касается puts eng, он печатает массив, возвращаемый array.each из to_english.

Смежные вопросы