红宝石单行和警告:'其他没有救援是没用的'

时间:2017-04-12 19:51:49

标签: ruby algorithm function if-statement

我正在尝试使用Ruby函数打印基本三角形图案,该函数仅接受n

的正奇数
def triangle(n, chars)
    puts "#{n} must be odd and positive" if n % 2 == 0 || n < 0 else (n + 1).times { |i| puts chars * i } 
end

问题是这个函数不仅接受奇数而且接受正数n。 triangle(3, '#')会打印

    #
    ##
    ###

但是'triangle(4,'#')'也可以正常使用

    #
    ##
    ###
    ####

似乎我的如果语句无法正常工作,我收到警告else without rescue is useless。为什么以及如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

Ruby将您的代码解释为两个单独的语句。

puts "#{n} must be odd and positive" if n % 2 == 0 || n < 0

else (n + 1).times { |i| puts chars * i } 

elseif无关。我猜想,Ruby在绝望中将其解释为begin/rescue/else condition的一部分。为什么它不是语法错误,我不知道,但它将其解释为没有begin块,这在技术上是成功的&#34;成功的&#34;所以else总是运行。

do this if that等条件语句仅适用于涵盖简单语句的简单条件。试图楔入其他条件是正确的。相反,使用正常情况。

def triangle(n, chars)
    if n % 2 == 0 || n < 0
        puts "#{n} must be odd and positive"    
    else
        (n + 1).times { |i| puts chars * i } 
    end
end

通常,请立即完全避免else处理错误情况。它避免了将大部分函数嵌套在else块中。这对于更长时间的功能更为重要,但这是一个很好的习惯。

def triangle(n, chars)
    if n % 2 == 0 || n < 0
        puts "#{n} must be odd and positive"
        return nil
    end

    (n + 1).times { |i| puts chars * i } 
end

最后,应该使用异常处理错误,而不是打印错误消息。调用者可以捕获并处理异常,打印的错误消息很难捕获并冒泡到用户。如果不处理例外,则停止该计划;如果用户忘记处理错误,程序将停止并且他们知道要修复它。打印的错误消息只是让程序向前推进,可以忽略,导致进一步的问题。

也可以对异常进行分类,允许调用者确定发生了什么类型的错误并采取适当的行动。

def triangle(n, chars)
    if n % 2 == 0 || n < 0
        raise ArgumentError, "#{n} must be odd and positive"
    end

    (n + 1).times { |i| puts chars * i } 
end

答案 1 :(得分:2)

问题似乎是流量控制与输出的逻辑混淆。我想这会做你想做的事:

def triangle(n, chars)
  if (n % 2 == 0) || (n < 0)
    puts "#{n} must be odd and positive"
  else
    (n + 1).times { |i| puts chars * i }
  end
end

答案 2 :(得分:0)

作为一个更优雅的实现,让我们更进一步,处理意外的参数

def triangle(n, chars='#')
  raise(ArgumentError, "{n} must be odd and positive") unless n.to_i.odd? && n.to_i > 0
  1.upto(n.to_i) { |i| chars.to_s * i} 
end

现在,这将处理响应n的任何to_i和响应chars的任何to_s。例如&#39; 13&#39;,[&#39; x&#39;,&#39; x&#39;,1]仍然是有效的参数,即使它们形成一个奇怪的三角形。

Ruby以这种方式非常支持duck typing,它使你的代码更少于特定于类型。