Implicit return values in Ruby

前端 未结 2 725
别那么骄傲
别那么骄傲 2020-12-05 14:23

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 w

相关标签:
2条回答
  • 2020-12-05 14:57

    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).

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

    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
    

    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
    
    0 讨论(0)
  • 2020-12-05 15:07

    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 the each method (which is now the last stmt), which turns out to be an array of matches.

    irb(main):014:0> "StackOverflow Meta".scan(/[aeiou]\w/).each do |match|
    irb(main):015:1* s << match
    irb(main):016:1> end
    => ["ac", "er", "ow", "et"]
    

    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..

    irb(main):003:0> one_to_three = (1..3).to_a
    => [1, 2, 3]
    irb(main):004:0> puts one_to_three
    1
    2
    3
    => nil
    

    Personally I find your method with the explicit return more readable (in this case)

    0 讨论(0)
提交回复
热议问题