在 Ruby 中,我可以在不创建新的全局变量的情况下从方法内部移交变量吗?

In Ruby, can I hand off variables from within a method without making new global variables?

我正在学习 Ruby 艰难之路中的游戏创作练习。它以命运为主题,因为那是我现在脑子里想的。

我想让玩家选择一个角色 class,然后让这个选择交出一些数字作为统计数据,以便稍后在游戏中检查。下面是实际工作的版本,但它涉及创建几个全局变量,我一直在阅读它不是 Ruby 中的 "best practice"。

我的问题是,有没有一种方法可以在不创建所有这些全局变量的情况下完成下面代码的操作,或者我正在做需要做的事情?

$might = 1
$agility = 1
$intellect = 1

def start
  puts "Make all decisions by pressing the corresponding number."
  puts "Choose your class:"
  puts "1. Titan"
  puts "2. Hunter"
  puts "3. Warlock"

  print "> "
  choice = $stdin.gets.chomp


  if choice == "1"
    $might = 3
    puts "You've chosen Titan!"
  elsif choice == "2"
    $agility = 3
    puts "You've chosen Hunter!"
  elsif choice == "3"
    $intellect = 3
    puts "You've chosen Warlock!"
  else
    puts "Try again."
    start
  end
end

puts start

puts "Might: #{$might}"
puts "Agility: #{$agility}"
puts "Intellect: #{$intellect}"

您可以创建一个 class 并使用实例变量:

class Game
  def initialize
    @might = 1
    @agility = 1
    @intellect = 1
  end
  attr_reader :might
  attr_reader :agility
  attr_reader :intellect
  def start
    puts "Make all decisions by pressing the corresponding number."
    puts "Choose your class:"
    puts "1. Titan"
    puts "2. Hunter"
    puts "3. Warlock"

    print "> "
    choice = $stdin.gets.chomp


    case choice 
      when "1"
        @might = 3
        puts "You've chosen Titan!"
      when "2"
        @agility = 3
        puts "You've chosen Hunter!"
      when "3"
        @intellect = 3
        puts "You've chosen Warlock!"
      else
        puts "Try again."
        start
    end
  end
end
game = Game.new
game.start

puts "Might: #{game.might}"
puts "Agility: #{game.agility}"
puts "Intellect: #{game.intellect}"

备注:

  • 我用 case 语句替换了你的 if 序列
  • attr_reader 定义了实例变量的属性访问器。

也许是这样的。我准备更新。

class Character
  attr_accessor :might, :agility, :intelect, :type
  def initialize(type, might = 1, agility = 1, intelect = 1)
    @type = type
    @might, @agility, @intelect = might, agility, intelect
  end

  def print_attributes
    puts "Type: #{@type}"
    puts "Might: #{@might}"
    puts "Agility: #{@agility}"
    puts "Intelect: #{@intelect}"
  end
end

class Player
  attr_reader :character
  def initialize(character)
    @character = character
  end
end

class Game
  CHARACTER_CLASSES = [
    {:type => "Titan", :might => 3, :agility => 1, :intelect => 1},
    {:type => "Hunter", :might => 1, :agility => 3, :intelect => 1},
    {:type => "Warlock", :might => 1, :agility => 1, :intelect => 3}
  ]

  attr_reader :player
  def initialize
    @player = nil
  end

  def start
    puts "Make all decisions by pressing the corresponding number."
    repeat = true
    while repeat
      puts "Choose your class:"
      CHARACTER_CLASSES.each_with_index do |char_config, i|
        puts "#{i+1}. #{char_config[:type]}"
      end

      choice = gets.chomp
      choice_i = choice.to_i
      unless choice_i == 0
        if char_data = CHARACTER_CLASSES[choice_i - 1]
          @player = Player.new( Character.new(char_data[:type], char_data[:might], char_data[:agility], char_data[:intelect]) )
          repeat = false
        end
      end
    end
  end
end

game = Game.new
game.start
game.player.character.print_attributes

一个选项可能是从方法中返回任何你想要的:

def start
  puts "Make all decisions by pressing the corresponding number."
  puts "Choose your class:"
  puts "1. Titan"
  puts "2. Hunter"
  puts "3. Warlock"

  print "> "
  choice = $stdin.gets.chomp

  case choice
  when '1'
    puts "You've chosen Titan!"
    {agility: 1, might: 3, intellect: 1}
  when '2'
    puts "You've chosen Hunter!"
    {agility: 3, might: 1, intellect: 1}
  when '3'
    puts "You've chosen Warlock!"
    {agility: 1, might: 1, intellect: 3}
  else
    puts "Try again."
    start
  end
end

hero = start

puts "Might: #{hero[:might]}"
puts "Agility: #{hero[:agility]}"
puts "Intellect: #{hero[:intellect]}"