1
0
Fork 0
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:
Jeremy Kemper 2007-09-24 23:00:42 +00:00
parent eca3b790b5
commit 8e78a4542e
3 changed files with 35 additions and 5 deletions

View file

@ -1,5 +1,7 @@
*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]
* Fixed cache_page to use the request url instead of the routing options when picking a save path #8614 [josh]

View file

@ -44,8 +44,29 @@ class Object
end
unless defined? instance_exec # 1.9
def instance_exec(*arguments, &block) #:nodoc:
block.bind(self)[*arguments]
module InstanceExecMethods #:nodoc:
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

View file

@ -216,8 +216,15 @@ class ObjectInstanceVariableTest < Test::Unit::TestCase
end
def test_instance_exec_passes_arguments_to_block
block = Proc.new { |value| [self, value] }
assert_equal %w(hello goodbye), 'hello'.instance_exec('goodbye', &block)
assert_equal %w(hello goodbye), 'hello'.instance_exec('goodbye') { |v| [self, v] }
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