3

我是 Ruby 和 Rails 的新手(从 Python 和 Python 框架切换)。我正在编写一个简单的仪表板网站,它显示有关硬盘 SMART 状态的信息。在这里,我编写了一个助手,如果它的值满足条件,则在相关 SMART 属性附近的表格单元格中显示一个徽章。起初,帮助程序代码与清单 1中一样简单,但后来我决定绘制特定驱动器的所有标记的摘要,以及表中各个 SMART 属性附近的标记。所以起初我添加了一个简单的方法,例如:

def smart_chk_device(attrs)
    attrs.each { |item| smart_chk_attr(item) }
end

但是这种方法不起作用,它导致整个属性数组输出到结果页面。当我按照清单 2制作它时,它才开始起作用,但我相信那里有问题,同样的事情可以用更简单的方式完成。请告诉我正确的 Ruby 方式。

清单 1:

module HomeHelper
    def smart_chk_attr(attr)
        case attr[:id].to_i
        when 1,197
            content_tag(:span, "Warning", :class => "label label-warning") if attr[:raw].to_i > 0
        when 5,7,10,196,198
            content_tag(:span, "Critical", :class => "label label-important") if attr[:raw].to_i > 0
        end
    end
end

清单 2(有效,但我不喜欢它):

module HomeHelper
    def smart_chk_attr(attr)
        case attr[:id].to_i
        when 1,197
            return content_tag(:span, "Warning", :class => "label label-warning") if attr[:raw].to_i > 0
        when 5,7,10,196,198
            return content_tag(:span, "Critical", :class => "label label-important") if attr[:raw].to_i > 0
        else
            return String.new
        end
        return String.new
    end

    def smart_chk_device(attrs)
        output = ""
        attrs.each { |item| output << smart_chk_attr(item) }
        return output.html_safe
    end
end

attrs是一个 Hash 数组,其中每个 Hash 包含键:id:raw以及 SMART 属性的数字代码及其 RAW 值,两者都在字符串中。

此外,如果删除清单 2 中的最后一个“return String.new”,RoR 会抱怨。为什么会这样?“案例”不是阻止了所有可能的案例,因此控制永远不会到达函数的末尾吗?

4

2 回答 2

3

我相信这会以相同的方式表现,并且要短得多:

module HomeHelper

  def smart_chk_attr(attr)
    return '' unless attr[:raw].to_i > 0
    case attr[:id].to_i
      when 1,197
        content_tag(:span, "Warning", :class => "label label-warning")
      when 5,7,10,196,198
        content_tag(:span, "Critical", :class => "label label-important")
      else ''
    end
  end

  def smart_chk_device(attrs)
    attrs.map { |item| smart_chk_attr(item) }.join.html_safe
  end

end

Ruby 方法返回最后一个表达式的值,因此摆脱整个方法的显式返回。另外,DRY:不要重复自己(attr[:raw] 检查)。在这种情况下,我在方法的开头用一个保护子句替换了那些。短路保护子句是个人喜好问题,但我喜欢它们,你会在很多 Ruby 代码中看到它们。

于 2012-08-16T21:12:54.507 回答
0

你的方法smart_chk_attr(attr)最后有一个额外的回报,它永远不会运行。

each是一个枚举器,当它完成遍历您提供的每个项目时,它会返回传递给它的原始对象,而不是内部修改过的东西。

如果您使用collect,您将获得一个包含修改后对象的数组。如果您想要一个字符串输出,您可以使用join它们将它们放入一个字符串中。加入还将选择如何加入您的项目。

def smart_chk_device(attrs)
  attrs.collect{ |item| smart_chk_attr(item) }.join.html_safe
end
于 2012-08-16T21:14:53.287 回答