Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it impossible to tell if a function is a generator function if .bind() has been called on it?

Looks like calling .bind(this) on any generator function breaks my ability to see if the function is a generator. Any ideas on how to fix this?

var isGenerator = function(fn) {
    if(!fn) {
        return false;
    }

    var isGenerator = false;

    // Faster method first
    // Calling .bind(this) causes fn.constructor.name to be 'Function'
    if(fn.constructor.name === 'GeneratorFunction') {
        isGenerator = true;
    }
    // Slower method second
    // Calling .bind(this) causes this test to fail
    else if(/^function\s*\*/.test(fn.toString())) {
        isGenerator = true;
    }

    return isGenerator;
}

var myGenerator = function*() {
}

var myBoundGenerator = myGenerator.bind(this);

isGenerator(myBoundGenerator); // false, should be true
like image 517
Kirk Ouimet Avatar asked Nov 06 '14 00:11

Kirk Ouimet


People also ask

How do you know whether a function is a generator?

A generator function is a function with one or more yield statements in it. Unlike regular functions, generator functions return generator objects. Meaning, when you call a generator function, it doesn't run the function.

How does Python know if a function is a generator?

Create Generators in PythonIf a function contains at least one yield statement (it may contain other yield or return statements), it becomes a generator function. Both yield and return will return some value from a function.

What does a generator function return when called?

Calling a generator function does not execute its body immediately; a generator object for the function is returned instead.

Which is the correct way to declare a generator function?

// Declare a generator function with a single return value function* generatorFunction() { return 'Hello, Generator!' } The Generator object returned by the function is an iterator. An iterator is an object that has a next() method available, which is used for iterating through a sequence of values.


2 Answers

Since .bind() returns a new (stub) function that only just calls the original with .apply() in order to attach the proper this value, it is obviously no longer your generator and that is the source of your issue.

There is a solution in this node module: https://www.npmjs.org/package/generator-bind.

You can either use that module as is or see how they solve it (basically they make the new function that .bind() returns also be a generator).

like image 91
jfriend00 Avatar answered Nov 02 '22 03:11

jfriend00


Yes, it is possible to tell if a function is a generator even if .bind() has been called on it:

function testIsGen(f) {
  return Object.getPrototypeOf(f) === Object.getPrototypeOf(function*() {});
}
like image 21
niry Avatar answered Nov 02 '22 03:11

niry