diff options
-rw-r--r-- | activesupport/CHANGELOG | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object_and_class.rb | 6 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/proc.rb | 12 | ||||
-rw-r--r-- | activesupport/test/core_ext/object_and_class_ext_test.rb | 6 | ||||
-rw-r--r-- | activesupport/test/core_ext/proc_test.rb | 12 |
5 files changed, 40 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 1d517d8862..c448efbefb 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Add Object#instance_exec, like instance_eval but passes its arguments to the block. (Active Support will not override the Ruby 1.9 implementation of this method.) [Sam Stephenson] + +* Add Proc#bind(object) for changing a proc or block's self by returning a Method bound to the given object. Based on why the lucky stiff's "cloaker" method. [Sam Stephenson] + * Fix merge and dup for hashes with indifferent access #3404 [kenneth.miller@bitfield.net] * Fix the requires in option_merger_test to unbreak AS tests. [Sam Stephenson] diff --git a/activesupport/lib/active_support/core_ext/object_and_class.rb b/activesupport/lib/active_support/core_ext/object_and_class.rb index 4856a9f5d5..d44afbd839 100644 --- a/activesupport/lib/active_support/core_ext/object_and_class.rb +++ b/activesupport/lib/active_support/core_ext/object_and_class.rb @@ -65,6 +65,12 @@ class Object #:nodoc: def to_json ActiveSupport::JSON.encode(self) end + + unless defined? instance_exec # 1.9 + def instance_exec(*arguments, &block) + block.bind(self)[*arguments] + end + end end class Class #:nodoc: diff --git a/activesupport/lib/active_support/core_ext/proc.rb b/activesupport/lib/active_support/core_ext/proc.rb new file mode 100644 index 0000000000..2ca23f62ef --- /dev/null +++ b/activesupport/lib/active_support/core_ext/proc.rb @@ -0,0 +1,12 @@ +class Proc #:nodoc: + def bind(object) + block, time = self, Time.now + (class << object; self end).class_eval do + method_name = "__bind_#{time.to_i}_#{time.usec}" + define_method(method_name, &block) + method = instance_method(method_name) + remove_method(method_name) + method + end.bind(object) + end +end diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb index 22e4c6b8b4..fc19183ede 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -111,4 +111,10 @@ class ObjectInstanceVariableTest < Test::Unit::TestCase object.instance_variable_set :@b, 2 assert_equal({'a' => 1, 'b' => 2}, object.instance_values) 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) + end + end diff --git a/activesupport/test/core_ext/proc_test.rb b/activesupport/test/core_ext/proc_test.rb new file mode 100644 index 0000000000..ca91a257b7 --- /dev/null +++ b/activesupport/test/core_ext/proc_test.rb @@ -0,0 +1,12 @@ +require 'test/unit' +require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/proc' + +class ProcTests < Test::Unit::TestCase + def test_bind_returns_method_with_changed_self + block = Proc.new { self } + assert_equal self, block.call + bound_block = block.bind("hello") + assert_not_equal block, bound_block + assert_equal "hello", bound_block.call + end +end
\ No newline at end of file |