在配对会话中,我们遇到了如何处理ruby nils的问题,以及csv解析(通过ruby的CSV包)是否会更好,如果它传回空字符串......
您可以在此处查看我们创建的规范:
https://github.com/mtc2013/LocalSupport/blob/seed-refactoring/spec/models/organization_spec.rb
我们正在尝试以csv形式处理来自文本文件的数据,我们遇到的问题是,如果传入的元素是零,我们提取邮政编码的处理将是barf,所以我们有这些悲伤的路径:
expect(Organization.extract_postcode('HARROW BAPTIST CHURCH, COLLEGE ROAD, HARROW')).to eq(nil)
expect(Organization.extract_postcode(nil)).to eq(nil)
实际上这个extract_postcode方法可能会返回一个空字符串。你可以看到我们在这里实现的代码:
https://github.com/mtc2013/LocalSupport/blob/seed-refactoring/app/models/organization.rb
def self.extract_postcode(address_with_trailing_postcode)
match = address_with_trailing_postcode && address_with_trailing_postcode.match(/\s*(\w\w\d\s* \d\w\w)/)
match && match[1]
end
我们仍然觉得这有点难看。在Objective C这样的东西你可以在nil对象上调用方法,它们返回nil。在ruby中他们会抛出异常,所以我们检查这个“匹配&&匹配[1]”操作,但这是推荐的吗?
另一种方法可能是确保CSV解析始终生成空字符串而不是nils,但感觉我们仍然需要保护我们的代码免受传入的nils。
我想我们的最终问题是这里的红宝石方式是什么?如果你有一个方法应该只是在传递一个nil时抛出错误?或者你应该抓住它们并且只返回零?如果是字符串操作方法,还是空字符串?
我想如果建议抛出nil错误那么我们应该专注于修复我们的CSV解析以将缺失的元素视为空字符串......或者更好的方法是捕获nil错误并重新抛出它们使用我们自己的自定义错误消息?
任何建议都非常感谢
答案 0 :(得分:2)
我认为您的extract_postcode
返回nil
是准确的。当没有从地址中提取的邮政编码时,这是一个很好的表示。如果该方法返回一个空字符串,并且您希望调用者处理该字符串,则调用代码仍然需要直接检查内容以决定如何处理该值(毕竟它不是有效或有用的邮政编码) )。空字符串邮政编码只对您有用,因为您可以安全地在其上调用String方法,但这忽略了您实际上没有邮政编码数据这一事实 - 您的代码迟早要承认这一事实。
使用类似extract_postcode
的方法名称,我认为在没有邮政编码数据时提出异常也是合理的。但是异常处理可能是获得所需逻辑流程的一种更尴尬的方式。
如果要存储在其他位置提取的数据,则可能值得考虑将返回值与设置方式进行对齐。如果您的数据库在邮政编码列中存储空值以表示“无邮政编码”,则Ruby中的nil值与空字符串的匹配程度更高。这样做可以节省表示之间的代码映射。
最终,AFAIK没有“Ruby方式”。自我一致,至少在整个应用程序中的任何层的上下文中,此代码在其中运行,将为您提供最佳回报。