如果变量存在,只在erb中执行代码?

时间:2016-10-08 17:21:15

标签: ruby

Ruby新手在这里刚开始使用带有.erb模板的Ruby而且我遇到了代码问题。我有一个刽子手游戏,它将.rb文件中的变量传递给.erb文件,一切正常,直到我尝试在初始加载时检查它(没有变量存在)并且它引发了错误。所以我想我会使用defined?if statement检查变量是否存在然后执行代码,如果不存在则忽略。我使用时工作正常:

<% if defined?bad_guesses %>
    <%= bad_guesses %>
<% end %>

但我需要的信息是一个数组,当我尝试使用像这样的.each或.times语句时:

<% if defined?bad_guesses %>
  <% bad_guesses.each do |i| %>
    <%= i %>
  <% end %>
<% end %>

我明白了:

  

的NoMethodError      

未定义的方法`each'代表nil:NilClass

     

C:/Projects/hangman/views/index.erb in singleton class

     
      
  1. &lt;%bad_guesses.each do | i | %GT;

  2. 中的hangman.rb   
  3. erb:index,:locals =&gt; {:game_status =&gt; game_status,:bad_guesses =&gt; bad_guesses,:good_guesses =&gt; good_guesses,:word =&gt;字}

  4.   

任何建议表示赞赏。

此外,这甚至是正确的方法吗?当您创建一个.erb模板,该模板使用从.rb文件中的类传入的变量时,如果它存在于模板中,您如何忽略它?

使用以下方式传递变量:

get '/' do
    if params['make'] != nil
        make = params['make'].to_i
        game_status, bad_guesses, good_guesses, word = Hangman.get_word(make)
    elsif params['guess'] != nil
        guess = params['guess'].to_s
        game_status, bad_guesses, good_guesses, word = Hangman.check_guess(guess)
    end
  erb :index, :locals => {:game_status => game_status, :bad_guesses => bad_guesses, :good_guesses => good_guesses, :word => word}
end

1 个答案:

答案 0 :(得分:1)

看着这个:

<% if defined?bad_guesses %>
  <% bad_guesses.each do |i| %>
    <%= i %>
  <% end %>
<% end %>

几点:

  1. defined?a风格不好;请改用defined?(bad_guesses)defined? bad_guesses
  2. defined?会检查是否已定义,因此如果您说foo = nil; defined? foo则为真。
  3. 你也可以使用它:

    defined?(bad_guesses) && bad_guesses
    

    另一方面,默认情况下,未定义的实例变量为nil

    # it shows undefined
    defined? @non_existing_var
    
    # but you can still check if it's truthy:
    puts "found" if @non_existing_var
    # it won't print anything
    

    类似于这方面的实例变量是哈希。未知密钥的默认值为nil。

    实例变量的问题是它们的范围不是局部的。相反,我建议将本地变量作为嵌套哈希发送:

    locals: { data: { foo: "bar" } }
    

    然后您可以安全地检查可能不存在的值:

    if data[:foo]
      # this runs
    elsif data[:non_existent]
      # this doesnt run
    end