我墙上的啤酒瓶有什么问题'在Ruby中循环

时间:2016-09-04 16:33:57

标签: ruby

我是初学者,我已经被困在下面一段时间了;我无法弄清楚我哪里出错了。

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

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测试时,这首歌打印得很好。

当我尝试创建新对象时,有人可以帮助解释为什么这不起作用吗?我知道它非常混乱,而且可能是一种冗长的方式,但是我认为尝试以我自己的方式去做我迄今为止学到的东西,这将是一种更好的学习方法。 / p>

谢谢!

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

2 个答案:

答案 0 :(得分:1)

实例变量@single_nums@big_nums是根据实例定义的,应该在初始化时设置。

@single_nums = {...@big_nums = {...移至initialize,它应该有效。

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

答案 1 :(得分:1)

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

将它们移到initialize或者像这样制作方法:

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

这使用 memoization ,因此您不会反复创建哈希。