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

查看:23
本文介绍了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("|") << "
"
      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("|") << "
"
          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("|") << "
"
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("
") # remember the final join
    end        
  end
end

根据您的具体情况,您可以使用几种有用的方法.在这个你可能想要使用 inject 除非 scan 返回的结果数量很高(处理数组然后合并它们比处理单个字符串更有效).

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("|") << "
"
      end
    end        
  end
end

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

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