mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Object#instance_exec produces fewer garbage methods.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7621 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
eca3b790b5
commit
8e78a4542e
3 changed files with 35 additions and 5 deletions
|
@ -1,5 +1,7 @@
|
||||||
*SVN*
|
*SVN*
|
||||||
|
|
||||||
|
* Object#instance_exec produces fewer garbage methods. [Mauricio Fernandez]
|
||||||
|
|
||||||
* Decode json strings as Dates/Times if they're using a YAML-compatible format. Closes #9614 [Rick]
|
* Decode json strings as Dates/Times if they're using a YAML-compatible format. Closes #9614 [Rick]
|
||||||
|
|
||||||
* Fixed cache_page to use the request url instead of the routing options when picking a save path #8614 [josh]
|
* Fixed cache_page to use the request url instead of the routing options when picking a save path #8614 [josh]
|
||||||
|
|
|
@ -42,10 +42,31 @@ class Object
|
||||||
values
|
values
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
unless defined? instance_exec # 1.9
|
unless defined? instance_exec # 1.9
|
||||||
def instance_exec(*arguments, &block) #:nodoc:
|
module InstanceExecMethods #:nodoc:
|
||||||
block.bind(self)[*arguments]
|
end
|
||||||
|
include InstanceExecMethods
|
||||||
|
|
||||||
|
# Evaluate the block with the given arguments within the context of
|
||||||
|
# this object, so self is set to the method receiver.
|
||||||
|
#
|
||||||
|
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
||||||
|
def instance_exec(*args, &block)
|
||||||
|
begin
|
||||||
|
old_critical, Thread.critical = Thread.critical, true
|
||||||
|
n = 0
|
||||||
|
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
||||||
|
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
||||||
|
ensure
|
||||||
|
Thread.critical = old_critical
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
send(method_name, *args)
|
||||||
|
ensure
|
||||||
|
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -216,8 +216,15 @@ class ObjectInstanceVariableTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_instance_exec_passes_arguments_to_block
|
def test_instance_exec_passes_arguments_to_block
|
||||||
block = Proc.new { |value| [self, value] }
|
assert_equal %w(hello goodbye), 'hello'.instance_exec('goodbye') { |v| [self, v] }
|
||||||
assert_equal %w(hello goodbye), 'hello'.instance_exec('goodbye', &block)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_instance_exec_with_frozen_obj
|
||||||
|
assert_equal %w(olleh goodbye), 'hello'.freeze.instance_exec('goodbye') { |v| [reverse, v] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_instance_exec_nested
|
||||||
|
assert_equal %w(goodbye olleh bar), 'hello'.instance_exec('goodbye') { |arg|
|
||||||
|
[arg] + instance_exec('bar') { |v| [reverse, v] } }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue