Ruby 中的隐式返回值
我对 Ruby 有点陌生,虽然我发现它是一种非常直观的语言,但我在理解隐式返回值的行为方式方面遇到了一些困难。
我正在开发一个小程序来 grep Tomcat 日志并根据相关数据生成管道分隔的 CSV 文件。 这是一个简化的示例,我用它来从日志条目生成行。
class LineMatcher
class << self
def match(line, regex)
output = ""
line.scan(regex).each do |matched|
output << matched.join("|") << "\n"
end
return output
end
end
end
puts LineMatcher.match("00:00:13,207 06/18 INFO stateLogger - TerminationRequest[accountId=AccountId@66679198[accountNumber=0951714636005,srNumber=20]",
/^(\d{2}:\d{2}:\d{2},\d{3}).*?(\d{2}\/\d{2}).*?\[accountNumber=(\d*?),srNumber=(\d*?)\]/)
当我运行此代码时,我得到以下结果,这是显式返回输出值时所期望的结果。
00:00:13,207|06/18|0951714636005|20
但是,如果我将 LineMatcher 更改为以下内容并且不显式返回输出:
class LineMatcher
class << self
def match(line, regex)
output = ""
line.scan(regex).each do |matched|
output << matched.join("|") << "\n"
end
end
end
end
然后我得到以下结果:
00:00:13,207
06/18
0951714636005
20
显然,这不是期望的结果。 感觉我应该能够摆脱输出变量,但不清楚返回值来自哪里。 此外,欢迎任何其他建议/改进可读性。
I am somewhat new to Ruby and although I find it to be a very intuitive language I am having some difficulty understanding how implicit return values behave.
I am working on a small program to grep Tomcat logs and generate pipe-delimited CSV files from the pertinent data. Here is a simplified example that I'm using to generate the lines from a log entry.
class LineMatcher
class << self
def match(line, regex)
output = ""
line.scan(regex).each do |matched|
output << matched.join("|") << "\n"
end
return output
end
end
end
puts LineMatcher.match("00:00:13,207 06/18 INFO stateLogger - TerminationRequest[accountId=AccountId@66679198[accountNumber=0951714636005,srNumber=20]",
/^(\d{2}:\d{2}:\d{2},\d{3}).*?(\d{2}\/\d{2}).*?\[accountNumber=(\d*?),srNumber=(\d*?)\]/)
When I run this code I get back the following, which is what is expected when explicitly returning the value of output.
00:00:13,207|06/18|0951714636005|20
However, if I change LineMatcher to the following and don't explicitly return output:
class LineMatcher
class << self
def match(line, regex)
output = ""
line.scan(regex).each do |matched|
output << matched.join("|") << "\n"
end
end
end
end
Then I get the following result:
00:00:13,207
06/18
0951714636005
20
Obviously, this is not the desired outcome. It feels like I should be able to get rid of the output variable, but it's unclear where the return value is coming from. Also, any other suggestions/improvements for readability are welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ruby 中的任何语句都会返回最后计算的表达式的值。
您需要了解最常用方法的实现和行为,才能准确了解您的程序将如何运行。
#each
返回您迭代的集合。 也就是说,以下代码将返回 line.scan(regexp) 的值。如果要返回执行结果,可以使用
map
,它的作用与each
相同,但返回修改后的集合。您可以根据您的具体情况使用多种有用的方法。 在这种情况下,您可能需要使用
inject
,除非scan
返回的结果数量很多(处理数组然后合并它们比处理单个字符串更有效) 。Any statement in ruby returns the value of the last evaluated expression.
You need to know the implementation and the behavior of the most used method in order to exactly know how your program will act.
#each
returns the collection you iterated on. That said, the following code will return the value of line.scan(regexp).If you want to return the result of the execution, you can use
map
, which works aseach
but returns the modified collection.There are several useful methods you can use depending on your very specific case. In this one you might want to use
inject
unless the number of results returned byscan
is high (working on arrays then merging them is more efficient than working on a single string).在 ruby 中,方法的返回值是最后一条语句的返回值。 您也可以选择显式返回。
在您的示例中,第一个代码段返回字符串
output
。 然而,第二个片段返回each方法返回的值(现在是最后一个stmt),结果是一个匹配数组。更新:但是,这仍然不能解释您在一行上的输出。 我认为这是一个格式错误,它应该在不同的行上打印每个匹配项,因为这就是
puts
打印数组的方式。 一点代码可以比我更好地解释它。就我个人而言,我发现带有显式返回的方法更具可读性(在本例中)
In ruby the return value of a method is the value returned by the last statement. You can opt to have an explicit return too.
In your example, the first snippet returns the string
output
. The second snippet however returns the value returned by theeach
method (which is now the last stmt), which turns out to be an array of matches.Update: However that still doesn't explain your output on a single line. I think it's a formatting error, it should print each of the matches on a different line because that's how
puts
prints an array. A little code can explain it better than me..Personally I find your method with the explicit return more readable (in this case)