Ruby: метод возврата без блока - PullRequest
0 голосов
/ 05 апреля 2011

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

Вот мой код:

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

Ответы [ 2 ]

0 голосов
/ 05 апреля 2011

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

Ваш to_tut не сохраняетВаши изменения, потому что блочная переменная "c" является копией фрагмента строки, а не ссылкой на часть строки (если бы это был ref, вы могли бы использовать << для добавления; "+ =" по-прежнемуне сработает, потому что он переназначает, а не меняет ссылку).Именно так работает each_char, так как строка не содержит ссылок. </p>

Если вы хотите изменить строку на месте, вам, вероятно, придется считать в обратном порядке, а затем вставлять '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 не работает, потому что array.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

Относительно того, почему ваш "put lan" возвращает один символ на строку- это потому что ваш to_english возвращает массив.Вы захотите позвонить в join, чтобы преобразовать его.

0 голосов
/ 05 апреля 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...