首页 > 解决方案 > ruby mixin 可以访问它所混入的类中存在的变量吗?

问题描述

我在终端上玩了一个井字游戏,我做了一个棋盘结构,并决定创建一个包含获胜条件的 mixin。

我的 mixin 有这段代码:

##check if 3 in a diagonal was made
    diagonal_win = [[0,4,8],[2,4,6]]
    ##Deconstruction
    diagonal_win.each_index do |item|
      d_counter = 0
      diagonal_win.each_index do |an_item|
        x,y = COORDINATES[diagonal_win[item][an_item]]
        if @structure[x][y] == 'X'
          d_counter += 1
        end #end of if block
      end #an_item end

其中 COORDINATES 哈希是指类中的常量,我使用 mixin,如下所示:

class Board
  include WinCondition
  COORDINATES = {
    1 => [0,0],
    2 => [0,1],
    3 => [0,2],
    4 => [1,0],
    5 => [1,1],
    6 => [1,2],
    7 => [2,0],
    8 => [2,1],
    9 => [2,2]
  }

不幸的是,这似乎不起作用。我知道我可以将 COORDINATES 变量引入 mixin,但我想知道您是否真的无法通过 mixin 访问类中的常量,或者我做错了什么。

标签: ruby

解决方案


不,因为COORDINATESinWinCondition指的是WinCondition::COORDINATES. 这是一个简单的例子。

module WinCondition
  def show_coordinates
    p COORDINATES
  end
end

class Board
  include WinCondition

  COORDINATES = {
    1 => [0, 0],
    2 => [0, 1],
    3 => [0, 2],
    4 => [1, 0],
    5 => [1, 1],
    6 => [1, 2],
    7 => [2, 0],
    8 => [2, 1],
    9 => [2, 2]
  }.freeze
end

Board.new.show_coordinates

test.rb:3:in `show_coordinates': uninitialized constant WinCondition::COORDINATES (NameError)

相反,使用类方法。

module WinCondition
  def show_coordinates
    p self.class.coordinates
  end
end

class Board
  include WinCondition

  COORDINATES = {
    1 => [0, 0],
    2 => [0, 1],
    3 => [0, 2],
    4 => [1, 0],
    5 => [1, 1],
    6 => [1, 2],
    7 => [2, 0],
    8 => [2, 1],
    9 => [2, 2]
  }.freeze
  
  def self.coordinates
    COORDINATES
  end
end

Board.new.show_coordinates

使用类方法访问数据,即使只是包装一个常量,也有一些优势。

  • 它允许子类覆盖.coordinates. 常量不能被覆盖。
  • 它允许子类和用户WinCondition决定如何实现.coordiantes. 它们不限于常数。

例如。

class DynamicBoard < Board
  def self.coordinates
    # maybe load them from a file or something
  end
end

推荐阅读