закрытый метод `chomp 'для nil: NilClass (NoMethodError) - PullRequest
0 голосов
/ 12 мая 2011

Я пытаюсь изучить Ruby путем преобразования Java-программы в Ruby, но я обнаружил ошибку, связанную с этим блоком кода:

  def create
    @user_input = String.new()
#   @word_arr = Array.new

  print "Enter the text to be converted to pig latin, EOF to quit: "
    while gets do
      STDOUT.flush
      @user_input = gets.chomp
      @word_arr = @user_input.string.split(' ')
      @word_arr.each { |x| puts x.engToLatin() + ' '}
      print "EOF to Quit"
      @user_input = ""

    end

  end

Я получаю эту ошибку:

EnglishToPigLatin.rb:14:in `create': private method `chomp' called for nil:NilClass (NoMethodError)
    from EnglishToPigLatin.rb:60

Это область вокруг строки 60:

#if __FILE__ == $0

  mg = EnglishToPigLatin.new
  mg.create

#end

По сути, я пытаюсь сделать, пока есть ввод, получить этот ввод, разделить его на отдельные словаи пропустите каждое слово с помощью метода преобразования Pig Latin.

Ответы [ 2 ]

5 голосов
/ 12 мая 2011

Похоже, вы пытаетесь получить вход внутри вашего цикла.

Попробуйте

loop do
  user_input = gets.chomp!
  word_arr = user_input.to_s.split(' ')
  word_arr.each { |x| puts x.engToLatin() + ' '}
  puts "EOF to Quit"
end

В противном случае вы пытаетесь получить следующую строку ввода, когда ее нет. Кроме того, do не требуется для оператора while.
Вам также не нужно сбрасывать @user_input на ''.

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

Также ваше условное всегда верно. gets будет блокироваться, пока не получит строку ввода. Вы можете использовать loop для бесконечного цикла, который заканчивается прерыванием.

Кроме того, вам не нужно очищать STDOUT, если вы используете puts для последней строки вместо print.

Все это может быть сценарий или метод в модуле. Экземпляр даже не нужно делать. И если вы это сделаете, вместо использования двух строк с вашим mg.create, вы должны определить метод initialize. Тогда он используется как конструктор, и все, что вы установили при создании экземпляра, должно быть помещено туда.

Все это можно сделать так:

loop do
  puts gets.chomp.split(' ').map{ |x| x.engToLatin() }.join(' ')
  puts "EOF to Quit"
end
2 голосов
/ 12 мая 2011

Марио ответ правильный.Но у меня есть следующие примечания.

  • Вы все еще можете использовать конструкцию while, как показано ниже.
  • +' ' подразумевает, что вы не хотите разрывать строки после каждого слова.Я изменил эту часть.map и join часто встречаются в подобных случаях.print не добавляет разрыв строки, в то время как puts делает.
  • Я не уверен, что вы пытаетесь сделать с STDOUT.flush.Если вы хотите прокручивать верхнюю часть экрана перед каждым выводом, используйте system('clear').
  • У вас есть метод entToLatin, и он должен работать, но это правило ruby ​​для использования подчеркивания, напримерeng_to_latin для методов (хотя есть несколько исключений).

Таким образом, более рубиновый способ будет:

def create
  print "Enter the text to be converted to pig latin, EOF to quit: "
  while input = gets.strip and input != 'EOF'
    system('clear')
    puts input.split(/\s+/).map{|x| x.engToLatin}.join(' ')
    puts "EOP to Quit"
  end
end

А если вы используете ruby ​​1.9.2,Вы можете сократить map так, чтобы:

def create
  print "Enter the text to be converted to pig latin, EOF to quit: "
  while input = gets.strip and input != 'EOF'
    system('clear')
    puts input.split(/\s+/).map(:engToLatin).join(' ')
    puts "EOP to Quit"
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...