Using Ruby Sinatra, @tasks.each do |task| requires check for defined?(task)
<p>I am checking out Sinatra using this <a href="https://www.sitepoint.com/just-do-it-learn-sinatra-i/" rel="nofollow">tutorial</a>.  In the index method, it selects all tasks:</p>

<pre><code>@tasks = Task.all
</code></pre>

<p>In the index view, it iterates all of those tasks:</p>

<pre><code>- @tasks.each do |task|
</code></pre>

<p>And, in the task partial, it displays the name:</p>

<pre><code>= task.name
</code></pre>

<p>As expected, the task partial iterates through the entire Task class, but it continues past the last task and finally fails:</p>

<pre><code>NameError - undefined local variable or method `task' for #&lt;Sinatra::Application:0x4e0db18&gt;:
</code></pre>

<p>This happens within the each iteration unless I test whether task, the each variable, is defined?</p>

<pre><code>- if defined?(task)
</code></pre>

<p>This is unexpected, to me.  Can someone explain it?</p>

<p>Main.rb:</p>

<pre><code># https://www.sitepoint.com/just-do-it-learn-sinatra-i/
require 'sinatra'
require 'slim'
require 'data_mapper'
require 'dm-sqlite-adapter'

DataMapper.setup(:default, ENV['DATABASE_URL'] || 'sqlite3:development.db')
class Task
  include DataMapper::Resource
  property :id,           Serial
  property :name,         String, :required =&gt; true
  property :completed_at, DateTime
end
DataMapper.finalize
DataMapper.auto_upgrade!

get '/' do
  @tasks = Task.all
  slim :index
end

post '/' do
  Task.create  params[:task]
  redirect to('/')
end

get '/:task' do
  @task = params[:task].split('-').join(' ').capitalize
  slim :task
end

delete '/task/:id' do
  Task.get(params[:id]).destroy
  redirect to('/')
end

put '/task/:id' do
  task = Task.get params[:id]
  task.completed_at = task.completed_at.nil? ? Time.now : nil
  task.save
  redirect to('/')
end
</code></pre>

<p>index.slim:</p>

<pre><code>form action="/" method="POST"
  input type="text" name="task[name]"
  input.button type="submit" value="New Task &gt;&gt;"

h2 My Tasks

ul.tasks
  - @tasks.each do |task|
    - if defined?(task)
      == slim(:task, locals: { task: task })
</code></pre>

<p>task.slim:</p>

<pre><code>li.task
  - if defined?(task)
    = task.name
    form.update action="/task/#{task.id}" method="POST"
      input type="hidden" name="_method" value="PUT"
      / Logic is bad here and will be fixed.
      - if task.completed_at.nil?
        input type="submit" value="  " title="Complete Task"
      - else
        input type="submit" value="✓" title="Uncomplete Task"
    form.delete action="/task/#{task.id}" method="POST"
      input type="hidden" name="_method" value="DELETE"
      input type="submit" value="&amp;times;" title="Delete Task"
</code></pre>