Why does Ruby use yield?

后端 未结 4 800
天命终不由人
天命终不由人 2020-12-30 05:14

I am new to Ruby. I have used a lot of C# and JavaScript which allow higher-order functions and I typically use them on a daily basis.

Ruby seems a little strange to

相关标签:
4条回答
  • 2020-12-30 05:18

    One advantage of yield is it also lets you use next (like continue) and break. In other languages, for next, you might have to use return, and for break, you might have to (ab)use exceptions. It is arguably nicer to have built-in support for these sorts of operations.

    0 讨论(0)
  • 2020-12-30 05:19

    In most cases, you execute the block right there in the method, using yield.

    The block is passed straight into the method, and the method can then call back to the block with the yield keyword.

    def a_method(a, b)
    a + yield(a, b)
    end
    a_method(1, 2) {|x, y| (x + y) * 3 } # => 10
    

    When you call back to the block, you can provide values for its arguments, just like you do when you call a method. Also, like a method, a block returns the result of the last line of code it evaluates.

    0 讨论(0)
  • 2020-12-30 05:21

    Yield Passes Objects to a Method's Block

    [Yield is] going to the origin of the call and grabbing a block immediately following the call.

    Not really. yield passes an argument to a block; it doesn't "grab a block" or do anything with it. In other words, this:

    def foo; yield self; end
    foo { |x| x.inspect }                                       
    # => "main"
    

    Here, yield isn't doing anything but passing an argument to the block that is passed into the foo method. Every Ruby method supports an optional block—except when a block is actually mandatory—so the only "magic" is that the language allows a block to be passed even when it isn't explicitly declared as part of the method signature.

    Further Examples

    To see this implicit signature in action, consider this:

    def foo; puts block_given?; end
    foo { |x| x.inspect }
    

    which will print "true" and return nil, which is the expected return value from the puts method.

    Of course, without yield the block doesn't do anything at all. For example:

    def foo; end
    foo { |x| x.inspect }
    # => nil
    
    0 讨论(0)
  • 2020-12-30 05:35

    Yield is Syntax Sugar

    This example of yield:

    def do_something_for_each(array)
      array.each do |el|
        yield(el)
      end
    end
    

    Is just syntax sugar for:

    def do_something_for_each(array, &block)
      array.each do |el|
        block.call(el)
      end
    end
    

    Pick the syntax you like and run wild with it.

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