如何使这个代码更像Ruby-way?

时间:2012-08-16 20:51:14

标签: ruby-on-rails ruby ruby-on-rails-3 view-helpers content-tag

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

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 是一个哈希数组,其中每个哈希包含:id :raw 键,其中包含SMART属性的数字代码,它的RAW值,都在字符串中。

此外,RoR投诉是否要删除清单2中的最后一个“return String.new”。为什么会这样? “case”是否阻止了所有可能的情况,因此控制永远不会到达函数的末尾?

2 个答案:

答案 0 :(得分: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代码中看到它们。

答案 1 :(得分:0)

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

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

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

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