こういうクラスがあったとして、

class Book
  attr_reader :author
end

以下のspecを書くと、

let(:author){ build :author, name: '田中'}

it 'test_a' do  
  book = Book.new
  book.instance_eval do
    @author = author
  end
  expect(book.author.name).to eq '田中'
end

undefined method or variables 'name' for nil class
になってしまいます。
しかし、

let(:author){ build :author, name: '田中'}

it 'test_a' do  
  # 一度ローカル変数に代入する。
  var_author = author
  book = Book.new
  book.instance_eval do
    @author = var_author
  end
  expect(book.author.name).to eq '田中'
end

にすれば解決します。
ブロックの中身ではletの値は取れずに、ブロックの外ではletの中身を取れます。
しかし、ブロックの中身も外もスコープの違いはないはずです。
letとはそもそもどういう働きなのでしょうか??なぜブロックの中身からletで定義した変数?を参照する事ができないのでしょうか。

※注意 Bookクラスは直面している問題をわかりやすくするためのモデルで、実際にはBookクラスでテストをしているわけではありません。