module Fidgit::RedirectorMethods
Redirects methods to an object, but does not mask methods and ivars from the calling context.
Public Instance Methods
instance_methods_eval() { |context| ... }
click to toggle source
Evaluate a block accessing methods and ivars from the calling context, but calling public methods (not ivars or non-public methods) on this object in preference.
# File lib/fidgit/redirector.rb, line 6 def instance_methods_eval(&block) raise ArgumentError, "block required" unless block_given? context = eval('self', block.binding) context.send :push_redirection_target, self begin yield context ensure context.send :pop_redirection_target end self end
Protected Instance Methods
pop_redirection_target()
click to toggle source
# File lib/fidgit/redirector.rb, line 54 def pop_redirection_target meta_class = class << self; self; end target, methods_to_recreate, methods_to_remove = redirection_stack.pop # Remove the redirection methods methods_to_remove.reverse_each do |meth| meta_class.send :remove_method, meth end # Replace with the previous versions of the methods. methods_to_recreate.reverse_each do |meth, reference, access| meta_class.send :define_method, meth, reference meta_class.send access, meth unless access == :public end target end
push_redirection_target(target)
click to toggle source
# File lib/fidgit/redirector.rb, line 23 def push_redirection_target(target) meta_class = class << self; self; end base_methods = Object.public_instance_methods # Redirect just the public methods of the target, less those that are on Object. methods_to_redirect = target.public_methods - base_methods # Only hide those public/private/protected methods that are being redirected. methods_overridden = [] [:public, :protected, :private].each do |access| methods_to_hide = meta_class.send("#{access}_instance_methods", false) & methods_to_redirect methods_to_hide.each do |meth| # Take a reference to the method we are about to override. methods_overridden.push [meth, method(meth), access] meta_class.send :remove_method, meth end end # Add a method, to redirect calls to the target. methods_to_redirect.each do |meth| meta_class.send :define_method, meth do |*args, &block| target.send meth, *args, &block end end redirection_stack.push [target, methods_overridden, methods_to_redirect] target end
Private Instance Methods
redirection_stack()
click to toggle source
Direct access to the redirection stack.
# File lib/fidgit/redirector.rb, line 75 def redirection_stack @_redirection_stack ||= [] end