嵌套If语句的Ruby方式
现在,我觉得把变量设置为一个值是一种非常丑陋的方式,取决于它是否返回空字符串。下面是讨论中的方法(它使用Nokogiri,但这对这个问题并不重要) 移除返回并让:嵌套If语句的Ruby方式,ruby,Ruby,现在,我觉得把变量设置为一个值是一种非常丑陋的方式,取决于它是否返回空字符串。下面是讨论中的方法(它使用Nokogiri,但这对这个问题并不重要) 移除返回并让: def get_let(response) if response.css('A').empty? response.css('B').empty? ? '' : response.css('B') else response.css('A') end end 或使用集合: d
def get_let(response)
if response.css('A').empty?
response.css('B').empty? ? '' : response.css('B')
else
response.css('A')
end
end
或使用集合:
def get_let(response)
['A', 'B'].map { |l| response.css(l) }.find { |items| !items.empty? } || ''
end
避免两次计算CSS选择器。我会这样做,非常明确地说明发生了什么,在推理时没有分支逻辑来跟踪它
def get_let(response)
return '' if response.css('A').empty? && response.css('B').empty?
return response.css('B') if response.css('A').empty?
return response.css('A') if response.css('B').empty?
end
您不需要
让它返回if/else块的结果就可以了。。。我更喜欢这样保存它,因为它比ternaries更容易阅读
def get_let(response)
if response.css('A').empty?
if response.css('B').empty?
''
else
response.css('B')
end
else
response.css('A')
end
end
这并不像@sethcall的答案那么易读,但如果您知道一些Ruby习惯用法,它应该是相当易读的:
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect { |response| !response.empty? } || ''
end
detect
返回块未返回false的第一个结果。这有避免条件句的优点,如果你想要的话。如果不想使用上述答案中的|
,可以执行以下操作:
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect(-> { '' }) { |response| !response.empty? }
end
不过,我觉得第二种解决方案不如第一种解决方案直观。如果您可以指定一个空字符串作为参数,那将是非常棒的。但是,detect
及其别名find
的参数必须是nil
或响应调用
方法的参数,如lambda或proc。实际上没有理由传入nil
,因为这是默认值
如果您确信response.css方法不会返回包含nil
或false
值的数组,则可以尝试以下解决方案:
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect(&:any?) || ''
end
请参阅Ruby文档以了解更多信息。以下是.您的问题是什么?如果response.css('A')和response.css('B')都为空,则find
的默认参数将引发此异常:NoMethodError:undefined方法“call”for“”:String
find
及其别名detect
要求参数1)为nil
,或2)响应调用
。查看我的答案,了解收集方法的一些替代实现。尼斯,忘记了这一点。这种方法的两个缺点是它有多个返回,并且返回是隐式的。如果您有一个方法的多个返回点,我建议使用return
关键字来明确它们。我知道return
通常不是很rubysh,但在这种情况下我会破例,因为使用它可以澄清代码。如果您使用Rails或ActiveSupport,您可以将其缩短为响应。检测(&:present)| |“
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect { |response| !response.empty? } || ''
end
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect(-> { '' }) { |response| !response.empty? }
end
def get_let(response)
responses = [response.css('A'), response.css('B')]
responses.detect(&:any?) || ''
end