迷你游戏。 Ruby 艰难的练习 35

Mini-game. Ruby the hard way exercise 35

我目前正在从 Learn Ruby the hard way tutorial. 中学习 ruby 在那个练习中,作者要求我们向一个简单的游戏中添加内容。但是,我试图通过这样做来改进 bear_room 方法

while true
print "> "
choice = gets.chomp.downcase!
if choice.include? ("taunt")
  dead("The bear looks at you then slaps your face off.")
elsif choice.include? "taunt" && !bear_moved
  puts "The bear has moved from the door. You can go through it now."
  bear_moved = true
elsif choice.include? "taunt" && bear_moved
  dead("The bear gets pissed off and chews your leg off.")
elsif choice.include? "open" && bear_moved

然而,当我这样写的时候:

choice = gets.chomp.downcase!

执行时出现此错误:

ex35.rb:44:in `bear_room': undefined method `include?' for nil:NilClass (NoMethodError)
from ex35.rb:99:in `start'
from ex35.rb:109:in `<main>'

但是如果这样做的话:

choice = gets.chomp.downcase

或者这个:

choice = gets.chomp
choice.downcase!

有效。 这是为什么? 如果能提供任何帮助,我将不胜感激。另外,while true 位是如何工作的? 这让我很困惑。

这是程序的其余部分,以备不时之需。我将保留 "separated" 提到的方法以使其更易于阅读。

# Creates the 'gold_room' method, so it can be called later.
def gold_room
  puts "This room is full of gold. How much do you take?"

  print "> "
  choice = gets.chomp
  # Converts the 'choice' variable to integer type.
  choice.to_i

  # Checks if 'choice' is equals to 0, OR greater or equal to 1.
  if choice == '0' || choice >= '1'
  # Saves the integer 'choice' variable in the 'how_much' variable.
    how_much = choice.to_i
  else
    dead("Man, learn to type a number.")
  end

  # Checks if the 'how_much' variable is lesser than 50, and executes the code below if so.
  if how_much < 50
    puts "Nice, you're not greedy, you win!"
    exit(0)
  elsif how_much >= 50 && how_much < 100
    puts "Mmm, ok that's enough. Get out!"
  else
    dead("You greedy bastard!")
  end
end


################### bear_room method ###################


# Creates the 'bear_room' method.
def bear_room
puts "There is a bear here."
puts "The bear has a bunch of honey."
puts "The fat bear is in front of another door."
puts "How are you going to move the bear?"
puts "1. Taunt the bear."
puts "2. Steal the bear's honey. "

# Declares the 'bear_moved' variable as a boolean, initialize it to false.
   bear_moved = false

  while true
    print "> "
    choice = gets.chomp.downcase
    if choice.include? ("taunt")
      dead("The bear looks at you then slaps your face off.")
    elsif choice.include? "taunt" && !bear_moved
      puts "The bear has moved from the door. You can go through it now."
      bear_moved = true
    elsif choice.include? "taunt" && bear_moved
      dead("The bear gets pissed off and chews your leg off.")
    elsif choice.include? "open" && bear_moved
      gold_room
    else
      puts "I got no idea what that means."
    end
  end
end

############### end of method ###############





# Defines the 'cthulhu_room' method.
def cthulhu_room
  puts "Here you see the great evil Cthulhu."
  puts "He, it, whatever stares at you and you go insane."
  puts "Do you flee for your life or eat your head?"

  print "> "
  choice = gets.chomp

  # Checks if the user's input contains the word 'flee'. If so, executes the code below.
  if choice.include? "flee"
    start
  # Checks if the user's input contains the word 'head'. If so, executes the code below instead.
  elsif choice.include? "head"
    dead("Well that was tasty!")
  else
    # Otherwise, calls the 'cthulhu_room' method again.
    cthulhu_room
  end
end

# Defines the 'dead' method. It takes one argument (why). Example: dead("Well that was tasty!")
def dead(why)
  puts why, "Nice."
  # Succesfully finish the program.
  exit(0)
end

# Defines the 'start' method, wich is where the game begins. Duh.
def start
  puts "You are in a dark room."
  puts "There is a door to your right and left."
  puts "Which one do you take?"

  print "> "
  choice = gets.chomp

  # Start the branching. It checks the user's input, and saves that on the 'choice' variable, which is used along the whole program in the other methods.
  if choice == "left"
    # Calls the 'bear_room' method.
    bear_room
  elsif choice == "right"
    # Calls the 'cthulhu_room' method.
    cthulhu_room
  else
    dead("You stumble around the room until you starve.")
  end
end

# Start the game.
start

-------------------------------------------- ------------------------------

TL;DR: choice = gets.chomp.downcase!

有什么区别
choice = gets.chomp
choice.downcase!

PS: 评论是练习的一部分。请,如果您有任何类型的更正(关于评论、我如何提出问题、一般代码等)告诉我,以便我可以改进。谢谢,抱歉太长了!

-------------------------------------------- --------------------------

那是因为如果字符串在调用 downcase! 时没有改变,它 returns nil。因此,当您尝试调用 include? 时,它说 nil 没有这样的方法。

因此,使用downcase的"non-destructive"版本是最安全的。 downcase! 方法会在可能的情况下就地改变字符串。

检查 docs 进一步阅读。