I'm having some trouble understanding scope in ruby.
Here is a link to a repo if you'd like to download/run what I'm talking about to see for yourself:
https://github.com/minervadreaming/killshit
I have several .rb files present - specifically, I'm having an issue calling a class method from an instance. Seems like I'm not properly following scope, but I'm not sure how or why.
Here is a snippet from 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
As you can see, when the player chooses to cast a spell it calls out to a Spells class, which I have in spells.rb. Here is a snippet from that code:
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
The problem is in the "Room.action" call at the end of the self.heal method (or just "action" as was my first attempt, as can be seen in the self.mp_check method). When it is hit, the following error is received:
spells.rb:27:in `heal': undefined method `action' for KillShit::Room:Class (NoMethodError)
I thought that it might've been because I needed to define "action" as a class method with "self." but that isn't doing it. I also thought that it's because I'm trying to call "action" from the Class itself as opposed to the instance of the class with which I am working, and so I should call .action but I can't figure out how to do so.
Any ideas? What should I be reading up on to better understand the concept behind what's happening here? Thanks!
您应该像这样调用Room#action方法:
KillShit::Room.action
Just after a brief look - you did not defined class but instance method action
.
Class methods need to by referenced with keyword self
or class name directly , so you would need fix the definition this way:
module KillShit
class Room
…
def self.action
…
end
…
end
end
Updated answer:
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 !
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.