如何…缩进… …结束…结束

我是ruby的新手,我想知道如何缩进这段代码:

if a.any? do |blah| name = blah[:name][/.* (.*)/, 1] name = convert_name(name) text = "#{name}#{blah[:value]}" text == "b2" end puts "found" exit 1 end 

我写的是这样的:

 if a.any? { |blah| (blah[:name] + blah[:value]) == "b2" } puts "found" exit 1 end 

要么:

 if a.any? { |blah| blah.values_at(:name, :value).join == "b2" } puts "found" exit 1 end 

实际测试足够短,可以在一行中完成。

通常我们在块返回值或在单行上时使用大括号( {} )。

在另一个字符串中插入两个字符串只是为了加入它们是臭的。 只是将它们连接起来; 你正在做的事情更明显。


如果您关心如何清楚地缩进,请考虑以下事项:

 if a.any? do |blah| name = blah[:name][/.* (.*)/, 1] name = convert_name(name) text = "#{name}#{blah[:value]}" text == "b2" end puts "found" exit 1 end 

any? 块应该比if块的内容进一步缩进,以便在视觉上将它们分开。 除了压痕……呃… any?代码块any? 应该重构为单行仍然。

像这样:

 if(a.any? { |blah| text = "#{blah[:name]}#{blah[:value]}"; text == "b2"}) puts "found" exit 1 end 

如果你any? 块真的很长,这样做:

 result = a.any? do |blah| text = "#{blah[:name]}#{blah[:value]}" text == "b2" ... end if(result) puts "found" exit 1 end 

我可能会把搜索逻辑扔进一个lambda:

 are_wanted = lambda do |blah| name = blah[:name][/.* (.*)/, 1] name = convert_name(name) text = "#{name}#{blah[:value]}" text == "b2" end 

然后,一旦它有一个名称,以便我们可以一目了然地告诉它是什么, if会变得美观和可读:

 if a.any?(&are_wanted) puts "found" exit 1 end 

当你最终得到一个复杂的Enumerable管道时,我发现这种技术非常有用,例如:

 pull_em_apart = lambda { ... } the_good_ones = lambda { ... } put_em_back_together = lambda { ... } array.map(&pull_em_apart) .select(&the_good_ones) .map(&put_em_back_together) 

lambda s超过一行时,比一大堆内联块更容易理解。

部分挑战是干净地容纳ifany? 块,因为两者都以end 。 那么,区分它们的一种方法是使用大括号作为内部块,以使其更清楚:

 if a.any? { |blah| name = blah[:name][/.* (.*)/, 1] name = convert_name(name) text = "#{name}#{blah[:value]}" text == "b2" } then puts "found" exit 1 end 

感谢Cary Swoveland建议then

另一个选择:

 begin puts "found" exit 1 end if a.any? do |blah| name = blah[:name][/.* (.*)/, 1] name = convert_name(name) text = "#{name}#{blah[:value]}" text == "b2" end