我是 Ruby 的初学者。我目前正在学习《Learn Ruby the Hard Way》的第 45 课,并正在创建一款类似于 Zork and Adventure 的游戏。
我创建了一个结构,在不同的文件中创建“场景”,并要求一个文件中的所有场景,其中我有一个引擎/ map ,确保当前场景不等于“完成”时运行“X” ' 场景的 'enter' 方法。
但是我有两个问题: 1)我不断收到一条错误消息“警告来自顶层的类变量访问” 2)即使脚本正在运行我得到
ex45.rb:30:in `play': undefined method `enter' for nil:NilClass (NoMethodError) from ex45.rb:59:in
以下是每个文件中的所有代码。如果读起来很长,我很抱歉,但我很想知道为什么会出现这两个错误以及我可以采取哪些措施来修复它们。
Ex45.rb:
require "./scene_one.rb"
require "./scene_two.rb"
require "./scene_three.rb"
@@action = SceneOne.new
@@action_two = SceneTwo.new
@@action_three = SceneThree.new
class Engine
def initialize(scene_map)
@scene_map = scene_map
end
def play()
current_scene = @scene_map.opening_scene()
last_scene = @scene_map.next_scene('finished')
while current_scene != last_scene
next_scene_name = current_scene.enter()
current_scene = @scene_map.next_scene(next_scene_name)
end
current_scene.enter()
end
end
class Map
@@scenes = {
'scene_one' => @@action,
'scene_two' => @@action_two,
'scene_three' => @@action_three
}
def initialize(start_scene)
@start_scene = start_scene
end
def next_scene(scene_name)
val = @@scenes[scene_name]
return val
end
def opening_scene()
return next_scene(@start_scene)
end
end
a_map = Map.new('scene_one')
a_game = Engine.new(a_map)
a_game.play()
scene_one.rb:
场景一类
def enter
puts "What is 1 + 2?"
print "> "
answer = $stdin.gets.chomp
if answer == "3"
puts "Good job"
return 'scene_two'
else
puts "try again"
test
end
end
end
场景_two.rb
class SceneTwo
def enter
puts "1 + 3?"
print "> "
action = $stdin.gets.chomp
if action == "4"
return 'scene_three'
else
puts "CANNOT COMPUTE"
end
end
end
场景_三.rb
class SceneThree
def enter
puts "This is scene three"
end
end
提前致谢!
最佳答案
回答您的第一个问题:
您需要将类变量定义移至 Map
类中以消除这些警告:
Ex45.rb:5: warning: class variable access from toplevel
Ex45.rb:6: warning: class variable access from toplevel
Ex45.rb:7: warning: class variable access from toplevel
因此,您的 Map
类将如下所示:
class Map
@@action = SceneOne.new
@@action_two = SceneTwo.new
@@action_three = SceneThree.new
@@scenes = {
'scene_one' => @@action,
'scene_two' => @@action_two,
'scene_three' => @@action_three
}
def initialize(start_scene)
@start_scene = start_scene
end
def next_scene(scene_name)
val = @@scenes[scene_name]
return val
end
def opening_scene()
return next_scene(@start_scene)
end
end
回答你的第二个问题:
您将得到undefined method 'enter' for nil:NilClass (NoMethodError)
,因为您的current_scene
在某个时刻变为nil
,然后您尝试调用:current_scene.enter()
,即nil.enter
,但失败并显示错误消息。
要解决此问题,您必须确保 current_scene
中始终具有某些值,即确保它不是 nil
。
我认为,您可以从 Engine
类中的 play
方法末尾删除 current_scene.enter()
行。因此,您的 Engine
类将如下所示:
class Engine
def initialize(scene_map)
@scene_map = scene_map
end
def play()
current_scene = @scene_map.opening_scene()
last_scene = @scene_map.next_scene('finished')
while current_scene != last_scene
next_scene_name = current_scene.enter()
current_scene = @scene_map.next_scene(next_scene_name)
end
# current_scene.enter()
end
end
而且,您将不会再收到该错误。
关于ruby-on-rails - 从顶层访问类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32804409/