module RSpec::Core::MemoizedHelpers::ClassMethods

def let(name, &block)

Other tags:
    Note: - Because `let` is designed to create state that is reset between
    Note: - `let` can be configured to be threadsafe or not.
    Note: - `let` _can_ enhance readability when used sparingly (1,2, or
def let(name, &block)
  # We have to pass the block directly to `define_method` to
  # allow it to use method constructs like `super` and `return`.
  raise "#let or #subject called without a block" if block.nil?
  raise(
    "#let or #subject called with a reserved name #initialize"
  ) if :initialize == name
  our_module = MemoizedHelpers.module_for(self)
  # If we have a module clash in our helper module
  # then we need to remove it to prevent a warning.
  #
  # Note we do not check ancestor modules (see: `instance_methods(false)`)
  # as we can override them.
  if our_module.instance_methods(false).include?(name)
    our_module.__send__(:remove_method, name)
  end
  our_module.__send__(:define_method, name, &block)
  # If we have a module clash in the example module
  # then we need to remove it to prevent a warning.
  #
  # Note we do not check ancestor modules (see: `instance_methods(false)`)
  # as we can override them.
  if instance_methods(false).include?(name)
    remove_method(name)
  end
  # Apply the memoization. The method has been defined in an ancestor
  # module so we can use `super` here to get the value.
  if block.arity == 1
    define_method(name) { __memoized.fetch_or_store(name) { super(RSpec.current_example, &nil) } }
  else
    define_method(name) { __memoized.fetch_or_store(name) { super(&nil) } }
  end
end