ruby-on-rails - 从顶层访问类变量

标签 ruby-on-rails ruby

我是 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/

相关文章:

ruby-on-rails - rails Assets 管道 "Cannot allocate memory - nodejs"

ruby-on-rails - React on Rails Gem - 工头雷神冲突

ruby-on-rails - Ruby %w 空值

ruby - Qt Ruby QListWidget Item添加数据后图标为空白

ruby-on-rails - 使用 Mongoid 的 MongoDB 对话/私有(private)消息模式

ruby-on-rails - 格式化 Rails 控制台输出

ruby - 调用 View 文件时如何传递参数?

ruby - 从嵌套哈希中删除特定元素

ruby - 使用 Ruby 按值过滤 JSON 数组

ruby-on-rails - 在模型中合并 Rails 4 中的两个范围