Ruby:范围和类/实例方法有问题

时间:2014-09-16 22:29:53

标签: ruby scope instance-variables class-variables

我在了解ruby中的范围时遇到了一些麻烦。

如果您想下载/运行我正在谈论的内容,请参阅回购链接:

https://github.com/minervadreaming/killshit

我有几个.rb文件 - 具体来说,我有一个问题从一个实例调用一个类方法。似乎我没有正确地遵循范围,但我不确定如何或为什么。

这是来自room.rb的片段:

module KillShit
    class Room
        attr_reader :player, :monster, :game

        def initialize(player, monster, game)
            @player = player
            @monster = monster
            @game = game
        end

        def action
            outline
            Player.describe(player)
            vs
            Monster.describe(monster)
            outline

            #rolling a d20 to see who takes a turn
            turn = rand(1..100)

            if turn <= 20
                monster_attack
            else
                puts "What would you like to do?"
                puts "1. Attack!"
                puts "2. Defend!"
                puts "3. Run away!"
                #Give the player magic if they're at least level 2
                if player.maglevel >= 1
                    puts "4. Cast spell"
                else
                end

                prompt; action = gets.chomp

                if action == "1"
                    attack(player, monster)
                elsif action == "2"
                    defend
                elsif action == "3"
                    flee
                elsif action == "4" && player.maglevel >= 1
                    magic
                else
                    action
                end
            end
        end

        def magic
            puts "What magic would you like to cast?"
            if player.maglevel == 1
                puts "1. Heal"
                puts "2. Fireball"
                puts "3. Tremor"
                prompt; magic = gets.chomp

                if magic == "1"
                    Spells.heal(player)
                elsif magic == "2"
                    Spells.fireball(player, monster)
                elsif magic == "3"
                    Spells.tremor(player, monster)
                else
                    magic
                end
            elsif player.maglevel == 2
                puts "1. Greater Heal"
                puts "2. Firestorm"
                puts "3. Earthquake"
                prompt; magic = gets.chomp

                if magic == "1"
                    Spells.greaterheal(player)
                elsif magic == "2"
                    Spells.firestorm(player, monster)
                elsif magic == "3"
                    Spells.earthquake(player, monster)
                else
                    magic
                end
            else
            end
        end
    end
end

正如你所看到的,当玩家选择施放一个咒语时,它会召唤一个Spells类,我在spells.rb中。以下是该代码的摘录:

require_relative 'room'
require_relative 'player'
require_relative 'monster'

module KillShit
    class Spells
        attr_accessor :player, :monster

    #Checking if user has enough MP to cast spell
        def self.mp_check(req, player)
            req_mp = req
            if player.mp < req_mp
                puts "#{player.name} doesn't have enough MP!"
                action
            else
            end
        end

        def self.heal(player)
            req_mp = 3
            Spells.mp_check(req_mp, player)

            player.mp -= req_mp
            amt = rand(3..10)
            player.hp += amt
            puts "#{player.name} has been healed by #{amt} HP!"
            Room.action
        end
    end
end

问题出在&#34; Room.action&#34;在self.heal方法结束时调用(或者只是&#34; action&#34;这是我的第一次尝试,如self.mp_check方法中所示)。当它被击中时,收到以下错误:

spells.rb:27:in `heal': undefined method `action' for KillShit::Room:Class (NoMethodError)

我认为这可能是因为我需要定义&#34;动作&#34;作为一种使用&#34; self的方法。&#34;但那并不是这样的。我也认为这是因为我试图打电话给&#34;动作&#34;从类本身而不是我工作的类的实例,所以我应该调用.action但我无法弄清楚如何这样做。

有什么想法吗?我应该阅读什么来更好地理解这里发生的事情背后的概念? 谢谢!

2 个答案:

答案 0 :(得分:2)

您应该调用Room#action方法,如:

KillShit::Room.action

答案 1 :(得分:0)

在简短的介绍之后 - 您没有定义类,而是实例方法action

类方法需要通过关键字self或类名直接引用,因此您需要以这种方式修复定义:

module KillShit
  class Room
    …
    def self.action
        …
    end
    …
  end
end

更新回答:

module KillShit
  class Room
    def self.action
      puts 'action in Room !'
    end
  end

  class Spells
    def self.heal(player)
      Room.action
    end
  end
end

KillShit::Spells.heal('Wallace')
# action in Room !