1

在配对会话中,我们遇到了如何处理 ruby​​ nils 的问题,以及 csv 解析(通过 ruby​​ 的 CSV 包)是否会更好,如果它传回空字符串......

您可以在此处查看我们创建的规范:

https://github.com/mtc2013/LocalSupport/blob/seed-refactoring/spec/models/organization_spec.rb

我们正在尝试处理 csv 格式的文本文件中的数据,如果传入的元素为 nil,我们提取邮政编码的处理将失败,因此我们有这些可悲的路径:

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​​ 中,它们会抛出异常,因此我们使用“match && match[1]”操作进行检查,但这是推荐的吗?

另一种方法可能是确保 CSV 解析始终生成空字符串而不是 nil,但感觉我们仍然需要保护我们的代码不被传入 nil。

我想我们最终的问题是这里的红宝石方式是什么?如果您有一个方法,它是否应该在通过 nil 时抛出错误?还是应该抓住它们然后返回 nil?或者如果它是字符串操作方法,则为空字符串?

我想如果建议抛出 nil 错误,那么我们应该只专注于修复我们的 CSV 解析以将丢失的元素视为空字符串......或者更好的方法是捕获 nil 错误并用我们自己的重新抛出它们自定义错误消息?

任何建议都非常感谢

4

1 回答 1

2

I think your extract_postcode returning nil is accurate. When there is no postcode to extract from an address, it is a good representation. If the method returned an empty string instead, and you expect caller to cope with that, the calling code would still need to check the contents directly for a decision on how to process that value (it isn't a valid or useful postcode after all). An empty string postcode is only useful to you in that you can safely call String methods on it, but that is ignoring the fact that you don't actually have postcode data - a fact your code will have to acknowledge sooner or later.

With a method name like extract_postcode I think it would also be reasonable to raise an exception when there was no postcode data. But exception handling might be a more awkward way of getting the logical flow you need.

If you are storing the data extracted elsewhere, it might be worth considering aligning the returned value with how that is set up. If your database stores nulls in the postcode column to represent "no postcode", then a nil value in Ruby is a better match to that than an empty string. Doing this will save you code mapping between representations.

Ultimately there isn't a "Ruby way" here AFAIK. Being self-consistent, at least in the context of whatever layer in your overall application this code operates within, will give you the best returns.

于 2013-04-27T21:50:21.123 回答