1
0
Fork 0
mirror of https://github.com/ms-ati/docile synced 2023-03-27 23:21:52 -04:00

Call #instance_exec on DSL object instead of proxy (#39)

when the DSL object is the same object as the block context object.

This short-circuits prior to performing setup (like copying ivars
from the block context to the proxy) that is unnecessary when the block
context and DSL object "match".

Add test that runs non-mutative code on frozen DSL object to check that
no FrozenError is raised, as it would have been if a
FallbackContextProxy tried to dynamically add methods to the DSL object.
This commit is contained in:
Matt Schreiber 2021-01-13 10:57:05 -05:00 committed by GitHub
parent 1b8676b426
commit 19c62d0d70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 1 deletions

View file

@ -2,7 +2,9 @@
## [Unreleased changes](http://github.com/ms-ati/docile/compare/v1.3.5...master)
...
- Short-circuit to calling #instance_exec directly on the DSL object (prior to
constructing a proxy object) when the DSL object and block context object are
identical
## [v1.3.5 (Jan 13, 2021)](http://github.com/ms-ati/docile/compare/v1.3.4...v1.3.5)

View file

@ -16,6 +16,13 @@ module Docile
# @return [Object] the return value of the block
def exec_in_proxy_context(dsl, proxy_type, *args, &block)
block_context = eval("self", block.binding)
# Use #equal? to test strict object identity (assuming that this dictum
# from the Ruby docs holds: "[u]nlike ==, the equal? method should never
# be overridden by subclasses as it is used to determine object
# identity")
return dsl.instance_exec(*args, &block) if dsl.equal?(block_context)
proxy_context = proxy_type.new(dsl, block_context)
begin
block_context.instance_variables.each do |ivar|

View file

@ -414,6 +414,12 @@ describe Docile do
expect(dsl.foo).to eq(0)
expect(dsl.bar).to eq(1)
end
context "when the DSL object is frozen" do
it "can call non-mutative code without raising an exception" do
expect { dsl.freeze.dsl_eval_string('1 + 2') }.not_to raise_error
end
end
end
context "when NoMethodError is raised" do