使用ARGV的Ruby练习

时间:2015-09-24 00:40:33

标签: ruby

我必须创建以下模式:

*
**
***
****
*****

使用ARGV这是我到目前为止所做的:

height = ARGV[0]
output = ""


height.to_i.times do |i|
  output << "*" * i
  output << "\n"
end
puts output

但是每次在mac终端上运行ruby pyramid.rb 5时,我都会得到以下输出:

$ ruby pyramid.rb 5

*
**
***
****

为什么在需要5个时才给我4个?

3 个答案:

答案 0 :(得分:4)

Integer#times会产生从0n-1的值,因此您可以获得0行至4星的行。

你提到这是一个练习,所以我会把修正案留给你。

一般来说,要解决这些问题,最好use a debugger或添加诊断打印(例如puts语句)来跟踪变量的值并确保它们是&#39;你的期望是什么。

例如,在这种情况下,您可以在循环中添加puts i以查看每次迭代时i的值是多少。您会看到类似0 1 2 3 4的内容,但这并不是您所期望的。从那里,您可以查看代码,文档或添加更多诊断输出,以确定为什么获得这些值。

答案 1 :(得分:0)

我知道此线程很旧,但我觉得迟到总比没有好。克里斯暗示了解决方案。如果i从零开始,只需添加i就可以使1i += 1开始。参见下面的示例:

height = ARGV[0]
output = ""
height.to_i.times do |i|
  i += 1
  output << "*" * i
  output << "\n"
end
puts output

答案 2 :(得分:0)

分析

您的代码中的问题是使用Integer#times。根据文档,#times方法:

  

[i]终止给定块int次,将值从零传递到int - 1

因此,这是您给定的代码,并带有注释:

height.to_i.times do |i| # when `height = 5`, equivalent to `(0..4).each`
  output << "*" * i      # will be "" on the first pass when i == 0
  output << "\n"
end

解决方案

在这种情况下,应使用1作为起始值,而不要使用Integer#upto方法。考虑下面的示例,将其重写为单行代码,您可以从命令提示符处运行它:

$ ruby -e '1.upto(Integer(ARGV[0])) { |i| puts "*" * i }' 5
*
**
***
****
*****

除了提供标准输出的预期结果外,它还消除了字符串突变,声明了 output 变量和其他非必需变量的情况。如果无法将 ARGV [0] 强制转换为整数,则使用Kernel#Integer也会引发异常,而是引入诸如ARGV[0] == ""时之类的细微错误。