aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Nagel2013-01-19 20:45:58 -0600
committerJack Nagel2013-01-21 17:24:11 -0600
commit8bb496febfec16a78336fc40eac81c758ac669c6 (patch)
treece2e8b764347032daaa9ad8437fe9bd152c40ceb
parentcfdc7efef925411efad291be5c6739979682b3b3 (diff)
downloadhomebrew-8bb496febfec16a78336fc40eac81c758ac669c6.tar.bz2
Object#instance_exec for Ruby 1.8.6
Not thread safe! But I don't think we care. We want to evaluate the env DSL block in the context of ENV for asthetic reasons, but we also want access to methods on the requirement instance. We can use #instance_exec to pass the requirement itself into the block: class Foo < Requirement env do |req| append 'PATH', req.some_path end def some_path which 'something' end end Also add a simplified version of Object#instance_exec for Ruby 1.8.6.
-rw-r--r--Library/Homebrew/build_environment.rb4
-rw-r--r--Library/Homebrew/dependencies.rb2
-rw-r--r--Library/Homebrew/extend/object.rb15
-rw-r--r--Library/Homebrew/global.rb1
-rw-r--r--Library/Homebrew/test/test_build_environment.rb14
-rw-r--r--Library/Homebrew/test/test_object.rb20
6 files changed, 53 insertions, 3 deletions
diff --git a/Library/Homebrew/build_environment.rb b/Library/Homebrew/build_environment.rb
index 18876f954..60e099977 100644
--- a/Library/Homebrew/build_environment.rb
+++ b/Library/Homebrew/build_environment.rb
@@ -18,9 +18,9 @@ class BuildEnvironment
@settings.include? :userpaths
end
- def modify_build_environment
+ def modify_build_environment(context=nil)
p = @settings.find { |s| Proc === s }
- ENV.instance_eval(&p) unless p.nil?
+ ENV.instance_exec(context, &p) unless p.nil?
end
def _dump(*)
diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb
index c2dd63d7d..54de50f39 100644
--- a/Library/Homebrew/dependencies.rb
+++ b/Library/Homebrew/dependencies.rb
@@ -190,7 +190,7 @@ class Requirement
# Overriding modify_build_environment is deprecated, pass a block to
# the env DSL method instead.
def modify_build_environment
- env.modify_build_environment
+ env.modify_build_environment(self)
end
def env
diff --git a/Library/Homebrew/extend/object.rb b/Library/Homebrew/extend/object.rb
new file mode 100644
index 000000000..8ffe5dc90
--- /dev/null
+++ b/Library/Homebrew/extend/object.rb
@@ -0,0 +1,15 @@
+class Object
+ def instance_exec(*args, &block)
+ method_name = :__temp_instance_exec_method
+ singleton_class = (class << self; self; end)
+ singleton_class.class_eval do
+ define_method(method_name, &block)
+ end
+
+ send(method_name, *args)
+ ensure
+ singleton_class.class_eval do
+ remove_method(method_name) if method_defined?(method_name)
+ end
+ end unless method_defined?(:instance_exec)
+end
diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb
index 6440506f8..50d30e877 100644
--- a/Library/Homebrew/global.rb
+++ b/Library/Homebrew/global.rb
@@ -3,6 +3,7 @@ require 'extend/pathname'
require 'extend/ARGV'
require 'extend/string'
require 'extend/symbol'
+require 'extend/object'
require 'utils'
require 'exceptions'
require 'set'
diff --git a/Library/Homebrew/test/test_build_environment.rb b/Library/Homebrew/test/test_build_environment.rb
index d8a227f51..6710662b5 100644
--- a/Library/Homebrew/test/test_build_environment.rb
+++ b/Library/Homebrew/test/test_build_environment.rb
@@ -31,6 +31,20 @@ class BuildEnvironmentTests < Test::Unit::TestCase
dump = Marshal.dump(@env)
assert Marshal.load(dump).userpaths?
end
+
+ def test_env_block
+ foo = mock("foo")
+ @env << Proc.new { foo.some_message }
+ foo.expects(:some_message)
+ @env.modify_build_environment
+ end
+
+ def test_env_block_with_argument
+ foo = mock("foo")
+ @env << Proc.new { |x| x.some_message }
+ foo.expects(:some_message)
+ @env.modify_build_environment(foo)
+ end
end
class BuildEnvironmentDSLTests < Test::Unit::TestCase
diff --git a/Library/Homebrew/test/test_object.rb b/Library/Homebrew/test/test_object.rb
new file mode 100644
index 000000000..debdd6c42
--- /dev/null
+++ b/Library/Homebrew/test/test_object.rb
@@ -0,0 +1,20 @@
+require 'testing_env'
+require 'extend/object'
+
+class InstanceExecTests < Test::Unit::TestCase
+ def test_evaluates_in_context_of_receiver
+ assert_equal 1, [1].instance_exec { first }
+ end
+
+ def test_passes_arguments_to_block
+ assert_equal 2, [1].instance_exec(1) { |x| first + x }
+ end
+
+ def test_does_not_persist_temporary_singleton_method
+ obj = Object.new
+ before = obj.methods
+ obj.instance_exec { methods }
+ after = obj.methods
+ assert_equal before, after
+ end
+end