Issue #12901 has been updated by Jeremy Evans.


It would probably be better if ruby could do analysis and if there are no references to local variables in the outer scope(s), automatically optimize such procs, so that you don't need to specify `scope: false`.  I believe JRuby already does that optimization.  I imagine it is fairly difficult to implement though.

In performance sensitive code, I've long used optimizations such as converting:

~~~ ruby
callable = lambda{|arg| puts arg}
~~~

to:

~~~ ruby
object = Object.new
def object.a(arg) puts arg end
callable = object.method(:a)
~~~

Having to do this to speed things up is kind of a pain, and I can see where a `scope: false` option would make manual optimization easier. I'm not against such an option, but if there are any plans to automatically optimize all procs that do not access the surrounding scope, this may not be needed.

----------------------------------------
Feature #12901: Anonymous functions without scope lookup overhead
https://bugs.ruby-lang.org/issues/12901#change-61239

* Author: Richard Schneeman
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Right now if you are writing performance sensitive code you can get a performance bump by not using anonymous functions (procs, lambdas, blocks) due to the scope lookup overhead.

https://twitter.com/apotonick/status/791167782532493312?lang=en

I would like to be able to create an anonymous function and specify I don't need it to perform the lookup when called.

I am thinking that this code:

~~~
Proc.new(scope: false) {|var| puts var }
~~~

Would be the equivalent of 

~~~
def anon(var)
  puts var
end
~~~

If you call it while trying to access something from outside of the scope it would error

~~~
var = "hello"
Proc.new(scope: false) { puts var }.call
# => NameError: undefined local variable or method `var' for main:Object
~~~

An example of a case where this could be used is found in https://github.com/rails/sprockets/pull/417. In this case we are getting rid of anonymous functions in favor of a method created with refinements. This solution works but it was not an obvious optimization. It would be convenient to have a syntax for defining anonymous functions that do not need access to caller scope.






-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>