Method: RSpec::Core::MemoizedHelpers::ClassMethods#let

Defined in:
lib/rspec/core/memoized_helpers.rb

#let(name, &block) ⇒ void

Note:

let can enhance readability when used sparingly (1,2, or maybe 3 declarations) in any given example group, but that can quickly degrade with overuse. YMMV.

Note:

let can be configured to be threadsafe or not. If it is threadsafe, it will take longer to access the value. If it is not threadsafe, it may behave in surprising ways in examples that spawn separate threads. Specify this on RSpec.configure

Note:

Because let is designed to create state that is reset between each example, and before(:context) is designed to setup state that is shared across all examples in an example group, let is not intended to be used in a before(:context) hook.

Generates a method whose return value is memoized after the first call. Useful for reducing duplication between examples that assign values to the same local variable.

Examples:


describe Thing do
  let(:thing) { Thing.new }

  it "does something" do
    # First invocation, executes block, memoizes and returns result.
    thing.do_something

    # Second invocation, returns the memoized value.
    thing.should be_something
  end
end


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/rspec/core/memoized_helpers.rb', line 284

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
  MemoizedHelpers.module_for(self).__send__(:define_method, name, &block)

  # 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