Class: Docile::FallbackContextProxy Private
- Inherits:
-
Object
- Object
- Docile::FallbackContextProxy
- Defined in:
- lib/docile/fallback_context_proxy.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
A proxy object with a primary receiver as well as a secondary fallback receiver.
Will attempt to forward all method calls first to the primary receiver, and then to the fallback receiver if the primary does not handle that method.
This is useful for implementing DSL evaluation in the context of an object.
rubocop:disable Style/MissingRespondToMissing
Direct Known Subclasses
Constant Summary collapse
- NON_PROXIED_METHODS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The set of methods which will not be proxied, but instead answered by this object directly.
Set[:__send__, :object_id, :__id__, :==, :equal?, :!, :!=, :instance_exec, :instance_variables, :instance_variable_get, :instance_variable_set, :remove_instance_variable]
- NON_FALLBACK_METHODS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The set of methods which will not fallback from the block's context to the dsl object.
Set[:class, :self, :respond_to?, :instance_of?]
- NON_PROXIED_INSTANCE_VARIABLES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The set of instance variables which are local to this object and hidden. All other instance variables will be copied in and out of this object from the scope in which this proxy was created.
Set[:@__receiver__, :@__fallback__]
Instance Method Summary collapse
-
#initialize(receiver, fallback) ⇒ FallbackContextProxy
constructor
private
A new instance of FallbackContextProxy.
-
#instance_variables ⇒ Array<Symbol>
private
Instance variable names, excluding NON_PROXIED_INSTANCE_VARIABLES.
-
#method_missing(method, *args, &block) ⇒ Object
private
Proxy all methods, excluding NON_PROXIED_METHODS, first to
receiver
and then tofallback
if not found.
Constructor Details
#initialize(receiver, fallback) ⇒ FallbackContextProxy
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of FallbackContextProxy.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/docile/fallback_context_proxy.rb', line 46 def initialize(receiver, fallback) @__receiver__ = receiver @__fallback__ = fallback # Enables calling DSL methods from helper methods in the block's context unless fallback.respond_to?(:method_missing) # NOTE: We could switch to {#define_singleton_method} on current Rubies singleton_class = (class << fallback; self; end) # instrument {#method_missing} on the block's context to fallback to # the DSL object. This allows helper methods in the block's context to # contain calls to methods on the DSL object. singleton_class. send(:define_method, :method_missing) do |method, *args, &block| m = method.to_sym if !NON_FALLBACK_METHODS.member?(m) && !fallback.respond_to?(m) && receiver.respond_to?(m) receiver.__send__(method.to_sym, *args, &block) else super(method, *args, &block) end end if singleton_class.respond_to?(:ruby2_keywords, true) singleton_class.send(:ruby2_keywords, :method_missing) end # instrument a helper method to remove the above instrumentation singleton_class. send(:define_method, :__docile_undo_fallback__) do singleton_class.send(:remove_method, :method_missing) singleton_class.send(:remove_method, :__docile_undo_fallback__) end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Proxy all methods, excluding NON_PROXIED_METHODS, first to receiver
and then to fallback
if not found.
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/docile/fallback_context_proxy.rb', line 91 def method_missing(method, *args, &block) if @__receiver__.respond_to?(method.to_sym) @__receiver__.__send__(method.to_sym, *args, &block) else begin @__fallback__.__send__(method.to_sym, *args, &block) rescue NoMethodError => e e.extend(BacktraceFilter) raise e end end end |
Instance Method Details
#instance_variables ⇒ Array<Symbol>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns Instance variable names, excluding NON_PROXIED_INSTANCE_VARIABLES.
85 86 87 |
# File 'lib/docile/fallback_context_proxy.rb', line 85 def instance_variables super.reject { |v| NON_PROXIED_INSTANCE_VARIABLES.include?(v) } end |