moduleRRmoduleInjectionsclassMethodMissingInjection<Injectionextend(Module.newdodeffind_or_create(subject_class)instances[subject_class]||=beginnew(subject_class).bindendenddefexists?(subject)instances.include?(subject)endend)BoundObjects={}includeClassInstanceMethodDefinedattr_reader:subject_classdefinitialize(subject_class)@subject_class=subject_class@placeholder_method_defined=falseenddefbindunlessclass_instance_method_defined(subject_class,original_method_alias_name)unlessclass_instance_method_defined(subject_class,:method_missing)@placeholder_method_defined=truesubject_class.class_evaldodefmethod_missing(method_name,*args,&block)superendendend# Ruby 1.9 will raise a NoMethodError when #method_missing is defined# on the subject, but #to_ary isn't. #method_missing will always be# defined thanks to BasicObject, but #to_ary may not, so in this case# we need to supply our own. Furthermore, Ruby has special logic to# handle the return value of #to_ary; if it is nil, then it tells Ruby# to ignore #to_ary altogether and use a default rule to arrayify the# object in question.unlessclass_instance_method_defined(subject_class,:to_ary)subject_class.class_evaldodefto_ary;nil;endendendsubject_class.__send__(:alias_method,original_method_alias_name,:method_missing)bind_methodendselfenddefresetifsubject_has_method_defined?(original_method_alias_name)memoized_original_method_alias_name=original_method_alias_nameplaceholder_method_defined=@placeholder_method_definedsubject_class.class_evaldoremove_method:method_missingunlessplaceholder_method_definedalias_method:method_missing,memoized_original_method_alias_nameendremove_methodmemoized_original_method_alias_nameendendendprotecteddefbind_methodid=BoundObjects.sizeBoundObjects[id]=subject_classifKeywordArguments.fully_supported?subject_class.class_eval((<<-METHOD),__FILE__,__LINE__+1)
def method_missing(method_name, *args, **kwargs, &block)
if respond_to_missing?(method_name, true)
super(method_name, *args, **kwargs, &block)
else
obj = ::RR::Injections::MethodMissingInjection::BoundObjects[#{id}]
MethodDispatches::MethodMissingDispatch.new(
self,
obj,
method_name,
args,
kwargs,
block
).call
end
end
METHODelsesubject_class.class_eval((<<-METHOD),__FILE__,__LINE__+1)
def method_missing(method_name, *args, &block)
if respond_to_missing?(method_name, true)
super(method_name, *args, &block)
else
obj = ::RR::Injections::MethodMissingInjection::BoundObjects[#{id}]
MethodDispatches::MethodMissingDispatch.new(
self,
obj,
method_name,
args,
{},
block
).call
end
end
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
METHODendenddeforiginal_method_alias_nameMethodDispatches::MethodMissingDispatch.original_method_missing_alias_nameendendendend