@@ -807,6 +807,9 @@ def assert_satisfactory_implementation(receiver, method_name, ruby_kwargs)
807807 end
808808 end
809809
810+ class ExtendedState
811+ attr_accessor :arguments , :object , :memos , :added_extras
812+ end
810813 # Wrap execution with hooks.
811814 # Written iteratively to avoid big stack traces.
812815 # @return [Object] Whatever the
@@ -817,20 +820,20 @@ def with_extensions(obj, args, ctx)
817820 # This is a hack to get the _last_ value for extended obj and args,
818821 # in case one of the extensions doesn't `yield`.
819822 # (There's another implementation that uses multiple-return, but I'm wary of the perf cost of the extra arrays)
820- extended = nil
821- value = run_extensions_before_resolve ( obj , args , ctx , extended ) do | obj , args , ext_extended |
822- # `ext_extended` may have been built up by the extensions:
823- extended = ext_extended
824- if extended && ( added_extras = extended [ : added_extras] )
823+ extended = ExtendedState . new
824+ extended . arguments = args
825+ extended . object = obj
826+ value = run_extensions_before_resolve ( obj , args , ctx , extended ) do | obj , args |
827+ if ( added_extras = extended . added_extras )
825828 args = args . dup
826829 added_extras . each { |e | args . delete ( e ) }
827830 end
828831 yield ( obj , args )
829832 end
830833
831- extended_obj = extended && extended . key? ( :obj ) ? extended [ :obj ] : obj
832- extended_args = extended && extended . key? ( :args ) ? extended [ :args ] : args
833- memos = extended && extended . key? ( : memos) ? extended [ :memos ] : EMPTY_HASH
834+ extended_obj = extended . object
835+ extended_args = extended . arguments
836+ memos = extended . memos || EMPTY_HASH
834837
835838 ctx . schema . after_lazy ( value ) do |resolved_value |
836839 idx = 0
@@ -850,27 +853,18 @@ def run_extensions_before_resolve(obj, args, ctx, extended, idx: 0)
850853 if extension
851854 extension . resolve ( object : obj , arguments : args , context : ctx ) do |extended_obj , extended_args , memo |
852855 if memo
853- extended ||= { }
854- memos = extended [ :memos ] ||= { }
856+ memos = extended . memos ||= { }
855857 memos [ idx ] = memo
856858 end
857859
858860 if ( extras = extension . added_extras )
859- extended ||= { }
860- ae = extended [ :added_extras ] ||= [ ]
861+ ae = extended . added_extras ||= [ ]
861862 ae . concat ( extras )
862863 end
863864
864- if !extended_obj . equal? ( obj )
865- extended ||= { }
866- extended [ :obj ] = extended_obj
867- end
868-
869- if !extended_args . equal? ( args )
870- extended ||= { }
871- extended [ :args ] = extended_args
872- end
873- run_extensions_before_resolve ( extended_obj , extended_args , ctx , extended , idx : idx + 1 ) { |o , a , ext | yield ( o , a , ext ) }
865+ extended . object = extended_obj
866+ extended . arguments = extended_args
867+ run_extensions_before_resolve ( extended_obj , extended_args , ctx , extended , idx : idx + 1 ) { |o , a | yield ( o , a ) }
874868 end
875869 else
876870 yield ( obj , args , extended )
0 commit comments