Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python yield vs Ruby yield

Tags:

python

yield

ruby

In Ruby, the yield keyword is used to yield to closures for blocks of execution.

How does this keyword differ in the Python language?

like image 539
Ben Nelson Avatar asked Feb 25 '16 22:02

Ben Nelson


People also ask

Should I use yield in Python?

We should use yield when we want to iterate over a sequence, but don't want to store the entire sequence in memory. Yield are used in Python generators. A generator function is defined like a normal function, but whenever it needs to generate a value, it does so with the yield keyword rather than return.

Is yield faster Python?

permutations. Using a generator (ie yield ) reduces this by approx. 20 % Using a generator and generating tuples is the fastest, about twice the time of itertools.

Is yield the same as return Python?

Difference between Python yield and ReturnYield is generally used to convert a regular Python function into a generator. Return is generally used for the end of the execution and “returns” the result to the caller statement.

Does yield return Ruby?

The yield keyword instructs Ruby to execute the code in the block. In this example, the block returns the string "yes!" .


2 Answers

In ruby, yield is a shortcut that is used to call an anonymous function. Ruby has a special syntax for passing an anonymous function to a method; the syntax is known as a block. Because the function has no name, you use the name yield to call the function:

def do_stuff(val)
  puts "Started executing do_stuff"
  yield(val+3)
  yield(val+4) 
  puts "Finshed executing do_stuff" 
end

do_stuff(10) {|x| puts x+3} #<= This is a block, which is an anonymous function
                            #that is passed as an additional argument to the 
                            #method do_stuff

--output:--
Started executing do_stuff
16
17
Finshed executing do_stuff

In python, when you see yield inside a function definition, that means that the function is a generator. A generator is a special type of function that can be stopped mid execution and restarted. Here's an example:

def do_stuff(val):
    print("Started execution of do_stuff()")

    yield val + 3
    print("Line after 'yield val + 3'")
    yield val + 4
    print("Line after 'yield val + 4'")

    print("Finished executing do_stuff()")


my_gen = do_stuff(10)

val = next(my_gen)    
print("--received {} from generator".format(val))

output:

Started execution of do_stuff()
--received 13 from generator

More code:

val = next(my_gen)    
print("--received {} from generator".format(val))

output:

Line after 'yield val + 3'
--received 14 from generator

From the output, you can see that yield causes a result to be returned; then execution is immediately halted. When you call next() again on the generator, execution continues until the next yield statement is encountered, which returns a value, then execution halts again.

like image 133
7stud Avatar answered Sep 22 '22 05:09

7stud


In Ruby, yield is used to bounce control to block( like anonymous function) to execute the block's statements and then bounce back to where the block's called.

With yield args you can pass arguments to the block, and also with lvar = yield you can get whatever returned and bind it to lvar after control exits the block. It's a much general and consistent feature design in Ruby. And of course, you can apply this idea to iterating over collections.

Whereas in Python, mostly people use yield to facilitate effective access of items over somewhat collection, they focus on iterate once and generate on the fly once being called idea, which is the main use of yield in Python.

FYI, It's not quite a distinguished feature between Python and Ruby on yield, at least on the way to use it. (Apparently they are implemented differently, as for python, yield creates a generator, which will not run any code unless the iteration starts). For example, the way yield is used in python contextmanager is quite the same in Ruby.

from contextlib import contextmanager
@contextmanager
def openfile(name, mode):
    f= open(name, mode)
    yield f
    f.close()

with openfile('log.txt', 'r') as handle:
    for line in handle:
        print line

here, yield pass file handle to with, and execute with-statements exactly once and then bounce back to file close statement

like image 38
Ze Gao Avatar answered Sep 22 '22 05:09

Ze Gao