我试图循环我的所有数组并尝试将我的json id的值与传递true方法的那个进行比较。但是当我尝试这样做时,我收到了一个错误:
undefined method 'each' for nil:NilClass
heroe.rb
require 'json'
class Hero
attr_accessor :hp
json = File.read('skill_list.json')
@skills = JSON.parse(json)
def initialize(name, level, job, hp, strength)
@name = name
@level = level.to_i
@job = job
@hp = hp.to_i
@strength = strength.to_i
end
def get_name
@name
end
def profile
puts "#{@name} level is #{@level} and hp: #{@hp}"
end
def attack(id)
@skills.each do |s|
if s['id'] == id
puts true
else
puts false
end
end
end
def get_hp
puts @hp
end
end
skill_list.json
[
{
"id": 0,
"name": "Double Slash",
"element": "fighter",
"amp": 1.1,
"mp": 1
}, {
"id": 1,
"name": "Slash",
"element": "fighter",
"amp": 1,
"mp": 1
}, {
"id": 2,
"name": "Falling Ashes",
"element": "psychic",
"amp": 1,
"mp": 1
}
]
然后我用攻击方法调用了对象:hero.attack(1)
我有点被困在这里,任何帮助都会受到赞赏〜
答案 0 :(得分:0)
因为实例变量必须在initialize方法或其他实例方法上声明,而不仅仅在类中声明。 我认为你应该在initialize方法中加入以下内容。
json = File.read('skill_list.json')
@skills = JSON.parse(json)
或将@skills移动到SKILLS常量,以便只调用一次。
class Hero
attr_accessor :hp
SKILLS = JSON.parse(File.read('skill_list.json'))
# ...
end
答案 1 :(得分:0)
主要问题是在类上下文中声明了@skills
,这使得它成为类的属性,而不是任何实例的属性。实例方法有各自独立的上下文,与此无关。与MyClass.a
和MyClass#a
不同,这里也适用。
修复此问题仅仅是将数据加载到具有延迟初始值设定项的类方法中一次:
class Hero
attr_accessor :name
attr_accessor :hp
attr_accessor :level
attr_accessor :strength
def self.skills
@skills ||= JSON.parse(File.open('skill_list.json'))
end
def initialize(name, level, job, hp, strength)
@name = name
@level = level.to_i
@job = job
@hp = hp.to_i
@strength = strength.to_i
end
def profile
puts "#{name} level is #{level} and hp: #{hp}"
end
def attack(id)
self.class.skills.each do |s|
if s['id'] == id
puts true
else
puts false
end
end
end
end
您还正在为attr_accessor
正确使用hp
,但后来定义了一个非常类似Ruby的get_hp
方法,这种方法完全无关紧要。您可以通过为每个属性使用访问器来摆脱它和其他get_
方法。