@@ -190,16 +190,12 @@ module ClassMethods
190
190
# end
191
191
# end
192
192
def let ( name , &block )
193
- # We have to pass the block directly to `define_method` to
194
- # allow it to use method constructs like `super` and `return`.
195
- raise "#let or #subject called without a block" if block . nil?
196
- MemoizedHelpers . module_for ( self ) . send ( :define_method , name , &block )
197
-
198
- # Apply the memoization. The method has been defined in an ancestor
199
- # module so we can use `super` here to get the value.
200
- define_method ( name ) do
201
- __memoized . fetch ( name ) { |k | __memoized [ k ] = super ( &nil ) }
202
- end
193
+ MemoizedHelpers . define_memoized_method (
194
+ self ,
195
+ name ,
196
+ MemoizedHelpers . memoized_method_name_for ( name , 'let' ) ,
197
+ &block
198
+ )
203
199
end
204
200
205
201
# Just like `let`, except the block is invoked by an implicit `before`
@@ -291,10 +287,11 @@ def let!(name, &block)
291
287
# @see MemoizedHelpers#should
292
288
def subject ( name = nil , &block )
293
289
if name
294
- let ( name , &block )
290
+ subject_method_name = MemoizedHelpers . memoized_method_name_for ( name , "subject" )
291
+ MemoizedHelpers . define_memoized_method ( self , name , subject_method_name , &block )
295
292
alias_method :subject , name
296
293
297
- self ::NamedSubjectPreventSuper . send ( :define_method , name ) do
294
+ self ::NamedSubjectPreventSuper . __send__ ( :define_method , subject_method_name ) do
298
295
raise NotImplementedError , "`super` in named subjects is not supported"
299
296
end
300
297
else
@@ -477,6 +474,26 @@ def self.module_for(example_group)
477
474
end
478
475
end
479
476
477
+ # @api private
478
+ def self . memoized_method_name_for ( name , let_or_subject )
479
+ "__rspec_#{ let_or_subject } _definition_#{ name } "
480
+ end
481
+
482
+ # @api private
483
+ def self . define_memoized_method ( example_group , name , memoized_method_name , &block )
484
+ # We have to pass the block directly to `define_method` to
485
+ # allow it to use method constructs like `super` and `return`.
486
+ raise "#let or #subject called without a block" if block . nil?
487
+
488
+ MemoizedHelpers . module_for ( example_group ) . __send__ ( :define_method , memoized_method_name , &block )
489
+
490
+ # Apply the memoization. The method has been defined in an ancestor
491
+ # module so we can use `super` here to get the value.
492
+ example_group . __send__ ( :define_method , name ) do
493
+ __memoized . fetch ( name ) { |k | __memoized [ k ] = send ( memoized_method_name , &nil ) }
494
+ end
495
+ end
496
+
480
497
if Module . method ( :const_defined? ) . arity == 1 # for 1.8
481
498
# @api private
482
499
#
0 commit comments