Ruby中的隐式返回值 [英] Implicit return values in Ruby

查看:108
本文介绍了Ruby中的隐式返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Ruby有点陌生,尽管我发现它是一种非常直观的语言,但在理解隐式返回值的行为方式方面还是有些困难.

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.

我正在开发一个小程序,用于grep Tomcat日志并根据相关数据生成管道分隔的CSV文件.这是我用来从日志条目生成行的简化示例.

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

但是,如果我将LineMatcher更改为以下内容,并且未明确返回输出:

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

然后我得到以下结果:

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.

推荐答案

ruby​​中的任何语句都返回最后一个求值表达式的值. 您需要了解最常用方法的实现和行为,才能准确了解程序的工作方式.

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返回您迭代的集合.也就是说,以下代码将返回line.scan(regexp)的值.

#each returns the collection you iterated on. That said, the following code will return the value of line.scan(regexp).

line.scan(regex).each do |matched|
  output << matched.join("|") << "\n"
end

如果要返回执行结果,可以使用map,它用作each,但返回修改后的集合.

If you want to return the result of the execution, you can use map, which works as each but returns the modified collection.

class LineMatcher
  class << self
    def match(line, regex)
      line.scan(regex).map do |matched|
        matched.join("|")
      end.join("\n") # remember the final join
    end        
  end
end

根据具体情况,可以使用几种有用的方法.在此示例中,除非scan返回的结果数量很多(使用数组然后合并它们比使用单个字符串更有效),否则您可能要使用inject.

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 by scan is high (working on arrays then merging them is more efficient than working on a single string).

class LineMatcher
  class << self
    def match(line, regex)
      line.scan(regex).inject("") do |output, matched|
        output << matched.join("|") << "\n"
      end
    end        
  end
end

这篇关于Ruby中的隐式返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆