【问题标题】:What's wrong with my 'Bottles of beer on the wall' loop in Ruby我在 Ruby 中的“墙上的啤酒瓶”循环出了什么问题
【发布时间】:2016-09-04 16:33:56
【问题描述】:

我是一个初学者,我已经被困在下面一段时间了;我不知道我哪里错了。

我正在尝试编写一个程序,在歌曲的每次迭代中打印出“Bottles of Beer”歌曲,输入一个数字并将其翻译成等效的英文单词。 当我尝试运行整个程序时,我收到错误消息:

in `english_words': undefined method `[]' for nil:NilClass (NoMethodError)
    from 11_classes.rb:83:in `block in print_song'
    from 11_classes.rb:78:in `downto'
    from 11_classes.rb:78:in `print_song'
    from 11_classes.rb:116:in `<main>'

但是当我在 irb 中测试时,这首歌的打印效果很好。

请有人帮忙解释为什么当我尝试创建一个新对象时这不起作用?我知道这很混乱,而且可能是一种冗长的方法,但我认为用我目前所学的东西尝试以我自己的方式去做会是一种更好的学习方式。

谢谢!

class BeerSong 

 attr_accessor :bottles

 def initialize(bottles)
  bottles = 0 if bottles < 0
  bottles = 99 if bottles > 99
  @bottles = bottles
 end

 @single_nums = { 
  19 => "Nineteen",
  18 => "Eighteen",
  17 => "Seventeen",
  16 => "Sixteen",
  15 => "Fifteen",
  14 => "Fourteen",
  13 => "Thirteen",
  12 => "Twelve",
  11 => "Eleven",
  10 => "Ten",
  9 => "nine",
  8 => "eight",
  7 => "seven",
  6 => "six",
  5 => "five",
  4 => "four",
  3 => "three",
  2 => "two",
  1 => "one",
  0 => "Zero"
  }

 @big_nums = {
  9 => "Ninety",
  8 => "Eighty",
  7 => "Seventy",
  6 => "Sixty",
  5 => "Fifty",
  4 => "Fourty",
  3 => "Thirty",
  2 => "Twenty"
  }


 def print_song
  @bottles.downto 1 do |n|
   if @bottles.zero?
    String.new
   else
    puts """
     #{english_words(n)} #{bottle(n)} of beer on the wall,
     #{english_words(n)} #{bottle(n)} of beer,
     Take one down, pass it around,
     #{english_words(n-1)} #{bottle(n+1)} of beer on the wall.
     """
   end
  end
 end

 def english_words(bottles)
   if bottles <= 19
    @single_nums[bottles].capitalize
   elsif bottles % 10 == 0
    split_number = bottles.to_s.split('').map(&:to_i)
    @big_nums[split_number[0]]
   else
    split_number = bottles.to_s.split('').map(&:to_i)
    "#{@big_nums[split_number[0]]}-#{@single_nums[split_number[1]]}"
   end
 end

 def bottle(n)
  if n == 1
   'bottle' 
  else 
   'bottles' 
  end
 end
end

【问题讨论】:

  • 能否请您添加什么不起作用,您看到什么错误以及预期的行为是什么?
  • 啊,是的,抱歉,我已经更新了我的问题——谢谢!

标签: ruby


【解决方案1】:

实例变量@single_nums@big_nums是根据实例定义的,应该在initialize中设置。

@single_nums = {...@big_nums = {... 移动到initialize,它应该可以工作。

或者您可以将它们设为常量:SINGLE_NUMS = {...BIG_NUMS = {... 并将它们留在原处。

【讨论】:

    【解决方案2】:

    您指的是实例方法中的@single_nums@big_nums。但是您在类上下文中声明了这些。

    将它们移动到initialize 或使它们成为这样的方法:

    def big_nums
      @big_nums ||= {
        ...your values here...
      }
    end
    

    这使用 memoization,因此您不会一遍又一遍地创建散列。

    【讨论】:

      猜你喜欢
      • 2020-04-03
      • 2016-10-06
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 2014-10-31
      • 2018-07-17
      • 1970-01-01
      • 2015-01-09
      相关资源
      最近更新 更多