简体   繁体   中英

Syntax Error: unexpected $end when using if/else if?

I'm getting an error from one of my controller classes and I can't figure out why. The error is:

SyntaxError in TermsController#show, syntax error, unexpected $end, expecting keyword_end

Here is terms_controller.rb:

class TermsController < ApplicationController

    def show
        @term = Term.find(params[:id])
        if @term.id == 1
            @title = "Fall"
        else if @term.id == 2
            @title = "Winter"
        else if @term.id == 3
            @title = "Spring"
        else if @term.id == 4
            @title = "Summer"
        end 
    end 
end 

My show page currently just consists of:

<h1> <%= @title %> </h1>

It's probably something small that I'm just missing - thanks for your help!

The issue that there are not enough end keywords and it found $end (the token representing the end of the file ) before it could find what it was looking for -- another end . (The parser token for the end keyword is either "keyword_end" or "Kend", depending upon ruby version.)

Each if expression requires a matching end keyword.

To get around this, use elsif instead of else if . It is part of the same if construct and does not require a matching end (only the if requires the matching end ).

   if x == 1
     "1"
   elsif x == 2
     "2"
   else
     "else"        
   end

Another option is case which works well if all branches check the same conditional operand ( x in this case):

   case x
     when 1 then "1"
     when 2 then "2"
     else "else"
   end

If you do want to use else if (remember, each if starts a new if conditional construct) then make sure close each block that a if opens. I have indented the code to show this point better.

   if x == 1
     "1"
   else
     if x == 2
       "2"
     else
       "else"
     end
   end

Happy coding.


For the pedantic: there is also another form of if , which is expr if cond , which doesn't have a matching end as part of the syntax and the rules talked about above do not apply to it.

In addition, if and case are just expressions in Ruby, so it might be more idiomatically written like this

@term = Term.find(params[:id])
@title = case @term.id
   when 1 then "Fall"
   when 2 then "Winter"
   when 3 then "Spring"
   when 4 then "Summer"
   else "Invalid Term"
end 

The if/elsif/end syntax can be used in the same way, but using case avoids the repeated mentioning of @term.id . Another option is to use a Hash to perform this sort of simple mapping -- or the mapping can be encapsulated in a separate method -- but that is covered elsewhere ;-)

而不是else if使用elsif

Why not just do this:

class TermsController < ApplicationController

  @@seasons = { 1 => "Fall", 2 => "Winter", 3 => "Spring", 4 => "Summer"}

  def show
    @term = Term.find(params[:id])
    @title = @@seasons[params[:id]] || "Invalid Season"
  end

end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM