更好的分配和检查结果的方法

时间:2012-09-05 06:57:48

标签: ruby

我必须使用String.scan函数,如果没有匹配则返回空数组。

我想用扫描函数分配一个变量并检查它是否匹配,但遗憾的是我不能这样做,因为它不会在没有匹配时返回nil或false。

我想这样做(1行):

if ip = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
  ...
  #use ip
end

但是因为在不匹配时它不会返回nil我必须这样做:

ip_match = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
unless ip_match.empty?
  #use ip
end

是否有一些更优雅的方式来写这个 - 能够同时进行分配和空检查或其他方式美化代码?

由于

3 个答案:

答案 0 :(得分:2)

由于扫描会返回一个数组,即使您确定只有一个结果,也可以这样做。

str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/).each do |ip|
  #use ip
end

答案 1 :(得分:1)

优雅与神秘或“简洁”之间存在差异。

在Perl中,你经常会看到人们写的内容相当于:

if (!(ip = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)).empty?)

它更简洁,简洁,紧凑,无论你想要什么。由于=(等同于)通常应该是相等测试,它还会导致维护问题。如果代码被传递给不理解逻辑的人,他们可能会错误地“纠正”那个,然后破坏代码。

在Ruby中,由于维护问题,在条件测试中不使用equate是惯用的,而是使用赋值后跟测试。这是更清晰的代码。

就个人而言,我更喜欢在这种情况下不使用unless。这是一个持续的讨论,unless是否有助于产生更易理解的代码;我更喜欢if (!ip_match.empty?),因为它更像我们通常会说的话 - 我很少在对话中用unless开始声明。您的里程可能会有所不同。

答案 2 :(得分:1)

我最好使用String助手match

执行此类操作
ip_validator = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/

# match return nil if no match

if str.match ip_validator 
  # blah blah blah.....
end

帮我保持干净清洁。    可能这不是最优雅的,如果有的话寻找其他人:)

您的ip_validator正则表达式似乎是周检查Rails 3: Validate IP String