【问题标题】:Ruby doesn't recognize `downcase` or `split` as defined methods? [duplicate]Ruby 不将“downcase”或“split”识别为已定义的方法? [复制]
【发布时间】:2017-02-06 18:28:08
【问题描述】:

问题在于以下代码:

#write your code here
def translate phrase
  phrase = phrase.downcase.split(/ /)
  phrase.collect! do |word|
    word = word.split(//)
    switched = false
    while switched == false
      word.each_index do |letter| 
        if word[letter] == ("a" || "e" || "i" || "o" || "u")
          switched = true
          word = (word[letter..-1] + word[0..(letter-1)]).join + "ay"
        end
      end
    end
  end
  return phrase.join(" ")
end

puts translate("chocolate cream")
#Should return "ocolatechay eamcray"

当我运行它时,Ruby 只返回一个空行。因此,为了解决问题,我将定义加载到 repl 中。 repl 返回以下错误:

NoMethodError: undefined method `downcase' for #<RubyVM::InstructionSequence:0x000000016e8f88>
    from /home/adc/odin-project/web-development-101/21-ruby-tdd/ruby_tdd_project/learn_ruby/04_pig_latin/pig_latin.rb:3:in `translate'
    from /home/adc/.rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'

如果我从代码中删除 downcase,我会收到相同的错误消息,只是这次是 split

这里有什么问题? (我非常有信心 downcasesplit 不是问题。)

【问题讨论】:

  • phrase 来自哪里?正如您在错误消息中看到的,它不是字符串而是RubyVM::InstructionSequence
  • phrase 只是translate 方法的一个参数。我尝试将 phrase 定义为 repl 中的字符串,但这没有帮助。

标签: ruby


【解决方案1】:

If 返回一个空白字符串,因为您在 collect! 块内没有返回任何内容。返回word 就可以了:

def translate phrase
  phrase = phrase.downcase.split(/ /)
  phrase.collect! do |word|
    word = word.split(//)
    switched = false
    while switched == false
      word.each_index do |letter|
        if word[letter] == ("a" || "e" || "i" || "o" || "u")
          switched = true
          word = (word[letter..-1] + word[0..(letter-1)]).join + "ay"
        end
      end
    end
    word
  end
  return phrase.join(" ")
end

puts translate("chocolate cream")
#=> atechocolay amcreay

它看起来不像你所期望的那样返回,但它仍然比空白字符串好。

至于你在控制台中出现的奇怪错误信息,似乎是 REPL 特有的(可能是因为方法名translate)。

【讨论】:

  • 是的,使用translatephrase 似乎会引发错误(如果我更改任何一个术语,错误就会消失)。谢谢 - 这回答了问题,即使代码尚未按预期工作。
  • @adc 您在单词循环中分配单词的问题。请在此示例中给出您预期的答案puts translate("methods unavailable")
  • @arm2pro "ethodsmay availableay"
  • @adc 看看下面的解决方案!
  • @arm2pro,谢谢,但你能解释一下为什么我的不起作用吗?我不明白为什么在单词循环中分配单词是个问题——看起来你做了同样的事情。
【解决方案2】:

更新 1(我将如何编写此代码)

def translate phrase
  phrase = phrase.downcase.split(/ /)
  phrase.collect! do |word|
    word = word.split(//)

    word.each_index do |letter| 
      if ["a", "e", "i", "o", "u"].include?(word[letter])
        if letter == 0
          word = word[letter..-1].join + "ay"
        else
          word = (word[letter..-1] + word[0..(letter-1)]).join + "ay"
        end

        break
      end
    end

    word
  end

  return phrase.join(" ")
end

puts translate("chocolate cream")

更新 2(如果我对您的代码进行一些小改动以使其有用)

def translate phrase
  phrase = phrase.downcase.split(/ /)
  phrase.collect! do |word|
    word = word.split(//)
    switched = false
    while switched == false
      word.each_index do |letter| 
        if ["a", "e", "i", "o", "u"].include?(word[letter])
          switched = true
          if letter == 0
            word = word[letter..-1].join + "ay"
          else
            word = (word[letter..-1] + word[0..(letter-1)]).join + "ay"
          end
          break
        end
      end
    end
    word
  end
  return phrase.join(" ")
end

puts translate("chocolate cream")

说明

  1. "o"==("a" || "e" || "i" || "o" || "u")

    "o"== "a" || "o" == "e" || "o" == "i" || "o" == "o" || "o" == "u"

    语句不一样。第一个是假的

    (因为("a" || "e" || "i" || "o" || "u")=="a""o"!="a"),因为第二个是真的。

  2. 你需要内部 if 语句

    if letter == 0
      word = word[letter..-1].join + "ay"
    else
      word = (word[letter..-1] + word[0..(letter-1)]).join + "ay"
    end
    

    因为当单词以任何提到的元音开头时,然后

    word[letter..-1] + word[0..(letter-1)]

    语句将返回整个单词两次,因为字母将等于 0。

  3. 最后你需要在while循环之后返回word对象。

【讨论】:

  • 好的,所以我看到了两个主要变化。 word 现在是 letters 直到 == 要返回的最后一个单词,并且您使用的是 break 而不是我的 switched 想法。如果您能解释为什么这两项更改是必要的,我将不胜感激。
  • @adc 请看我的更新。
  • 感谢@arm2pro,但我仍然不确定为什么我的switched 想法不起作用?您的 Update 2 仅起作用,因为break 也在那里。
  • @adc 您可能会在 while 循环后错过 word 对象返回部分。我也添加了第 3 点。
  • @adc 看看没有中断你的循环word.each_index do |letter| 将继续,即使它第一次出现在单词中。最后你会得到错误的结果,即 for break 是为了中断那个循环并将它交给 while 循环,因为 switched=true 已经结束了。
猜你喜欢
  • 2018-10-16
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多