关于ruby中实例方法的问题。

时间:2017-06-20 18:54:05

标签: ruby class instance-variables class-method instance-methods

我有一个使用ruby类构建一个井字游戏的任务。

到目前为止,我是编程和自学的新手,但是被接受到一个程序中,需要对一些概念进行改进,以便在游戏中领先。

我理解大多数概念并让大多数规范文件适用于我的游戏,但我确实需要多次引用解决方案代码以帮助解决问题的最后一点。

  1. 在创建board类时,创建了两个使用空数组定义的方法。我以前从未见过这个,想知道发生了什么。当我进入我的IDE并创建一个名为[](空数组)和两个参数的方法时,我会遇到一个错误(语法错误,期望输入结束)试图运行它。看来这一定是你在设置课程时必须做的事情吗?

    我假设这些是getter和setter方法?

      def [](pos)
        row, col = pos
        grid[row][col]
      end
    
      def []=(pos, value)
        row, col = pos
        grid[row][col] = value
      end
    
  2. 在上面的代码中,grid是board类的实例变量。为什么可以在方法中使用实例变量而不在其前面添加“@”符号 - (@ grid,而不是grid)。这有点令人困惑,因为使用常规方法,如果在方法之外定义变量,则该方法无法识别它。为什么课内不同?

    #example 
    
    x = 6 
    
    def add(b)
      x + b
    end 
    
    => will return an error - local variable x is undefined.
    
  3. 以下是完整的董事会课程,以便更好地理解和回答问题。谢谢!

    class Board
      attr_reader :grid, :marks
    
      def initialize(grid = [])
        if grid.empty?
          @grid = Array.new(3) { Array.new(3) }
        else
          @grid = grid
        end
        @marks = [:X, :O]
      end
    
      def place_mark(pos, mark)
        grid[pos[0]][pos[1]] = mark
      end
    
      def [](pos)
        row, col = pos
        grid[row][col]
      end
    
      def []=(pos, value)
        row, col = pos
        grid[row][col] = value
      end
    
      def empty?(pos)
        grid[pos[0]][pos[1]].nil? ? true : false
      end
    
      def winner
        (grid + grid.transpose + diagnol).each do |win|
          return :X if win == [:X,:X,:X]
          return :O if win == [:O,:O,:O]
        end
        nil
      end
    
      def diagnol
        diag1 = [[0, 0], [1, 1], [2, 2]]
        diag2 = [[0, 2], [1, 1], [2, 0]]
    
        [diag1, diag2].map do |diag|
          diag.map {|row, col| grid[row][col]}
        end
      end
    
      def over?
        return true if grid.flatten.compact.size == 9 || winner
        return false if grid.flatten.compact.size == 0 || winner.nil?
      end
    
    
    end
    

2 个答案:

答案 0 :(得分:2)

  1. 是的,这是Board上数组对象的getter和setter。 (FWIW我认为这样做的Ruby样式很差,所以我将来不会在你自己的代码中使用它。我认为这也是你的IDE在这个方法上遇到问题的原因。
  2. 您可以在没有@的情况下使用grid,因为您的课程顶部有attr_reader声明。这将为类上公共的实例变量创建只读变量。它有效地创建了一个名为:

    的方法
    def grid
      @grid
    end
    

    您将无法执行grid = [],因为attr_reader仅创建只读方法。要创建读写访问器,可以使用attr_accessor。请注意,使用attr_方法会在类中公开有问题的变量,因此如果您想保留内部内容,则不会使用它们。

答案 1 :(得分:0)

有点晚了,但我也在研究这个,并在网上发现了这个。显然,对于具有类似网格的实例变量的类,它是语法糖。

  

语法糖

     

这些都是获得左下方的等效方法:

listOfBooks.addAll(Arrays.asList(book1, book2, ...));
     

语法糖允许我们用我们的方法调用Board#[]方法   方括号内的参数而不是in   方括号后的括号。

     

同样,以下是设置右上角的等效方法   正方形:

board.grid[2][0]
board.[](2, 0)
board[2, 0] # syntactic sugar
     

当然,如果我们懒得设置特殊的[]和[] =方法,   我们将使用语法糖方式。 :)

可以从以下链接中找到更多信息:

https://github.com/emgreen33/Practice/blob/master/W2D4/bracket-methods.md