ruby 中关于实例方法的问题。
Questions about instance methods in ruby.
我有一项任务是使用 ruby classes 构建一个井字游戏。
到目前为止,我对编程和自学还是个新手,但被一个项目录取了,需要完善一些概念才能在游戏中脱颖而出。
我了解大部分概念并获得了适用于我的游戏的大部分规格文件,但我确实需要多次参考解决方案代码以帮助解决最后一点问题。
在创建板 class 时,创建了两个使用空数组定义的方法。我以前从未见过这个,想知道发生了什么。当我进入我的 IDE 并创建一个名为 [](空数组)和两个参数的方法时,我会收到一个错误(语法错误,期望输入结束)试图 运行 它.看来这一定是你只能在设置class时才能做的事情?
我假设这些是 getter 和 setter 方法?
def [](pos)
row, col = pos
grid[row][col]
end
def []=(pos, value)
row, col = pos
grid[row][col] = value
end
上述代码中,grid是board的一个实例变量class。为什么可以在方法中使用实例变量而无需在其前面放置“@”符号 - (@grid,而不是 grid)。这有点令人困惑,因为对于普通方法,如果您在方法外部定义变量,则该方法无法识别它。为什么它在 classes 内部不同?
#example
x = 6
def add(b)
x + b
end
=> will return an error - local variable x is undefined.
下面是完整的公告板 class 以防理解和回答问题更有意义。谢谢!
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
- 是的,这是
Board
上数组对象的 getter 和 setter。 (FWIW 我认为这样做的 Ruby 风格很差,所以我以后不会在你自己的代码中使用它。我认为这就是为什么你的 IDE 也有这个方法的问题.
您可以在没有 @ 的情况下使用 grid
,因为 class 顶部的 attr_reader
声明。这为 class 上的 public 实例变量创建了一个只读变量。它有效地创建了一个名为:
的方法
def grid
@grid
end
您将无法执行 grid = []
,因为 attr_reader
仅创建一个只读方法。要创建读写访问器,您可以使用 attr_accessor
。请记住,使用 attr_
方法会使相关变量 public 在 class 上,因此如果您想保留一些内部内容,则不会使用它们。
有点晚了,但我也在调查这个并在网上找到了这个。显然,它是 类 的语法糖,带有类似网格的实例变量。
The Syntactic Sugar
These are all equivalent ways to get the bottom-left square:
board.grid[2][0]
board.[](2, 0)
board[2, 0] # syntactic sugar
The syntactic sugar allows us to call the Board#[] method with our
arguments inside of the square brackets themselves rather than in
parentheses following the square brackets.
Similarly, the following are equivalent ways to set the top-right
square:
board.grid[0][2] = :x
board.[]=(0, 2, :x)
board[0, 2] = :x # syntactic sugar
Naturally, if we bother to set up the special [] and []= methods,
we'll use the syntactic sugar way. :)
可以从这里找到更多信息 link:
https://github.com/emgreen33/Practice/blob/master/W2D4/bracket-methods.md
我有一项任务是使用 ruby classes 构建一个井字游戏。
到目前为止,我对编程和自学还是个新手,但被一个项目录取了,需要完善一些概念才能在游戏中脱颖而出。
我了解大部分概念并获得了适用于我的游戏的大部分规格文件,但我确实需要多次参考解决方案代码以帮助解决最后一点问题。
在创建板 class 时,创建了两个使用空数组定义的方法。我以前从未见过这个,想知道发生了什么。当我进入我的 IDE 并创建一个名为 [](空数组)和两个参数的方法时,我会收到一个错误(语法错误,期望输入结束)试图 运行 它.看来这一定是你只能在设置class时才能做的事情?
我假设这些是 getter 和 setter 方法?
def [](pos) row, col = pos grid[row][col] end def []=(pos, value) row, col = pos grid[row][col] = value end
上述代码中,grid是board的一个实例变量class。为什么可以在方法中使用实例变量而无需在其前面放置“@”符号 - (@grid,而不是 grid)。这有点令人困惑,因为对于普通方法,如果您在方法外部定义变量,则该方法无法识别它。为什么它在 classes 内部不同?
#example x = 6 def add(b) x + b end => will return an error - local variable x is undefined.
下面是完整的公告板 class 以防理解和回答问题更有意义。谢谢!
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
- 是的,这是
Board
上数组对象的 getter 和 setter。 (FWIW 我认为这样做的 Ruby 风格很差,所以我以后不会在你自己的代码中使用它。我认为这就是为什么你的 IDE 也有这个方法的问题. 您可以在没有 @ 的情况下使用
的方法grid
,因为 class 顶部的attr_reader
声明。这为 class 上的 public 实例变量创建了一个只读变量。它有效地创建了一个名为:def grid @grid end
您将无法执行
grid = []
,因为attr_reader
仅创建一个只读方法。要创建读写访问器,您可以使用attr_accessor
。请记住,使用attr_
方法会使相关变量 public 在 class 上,因此如果您想保留一些内部内容,则不会使用它们。
有点晚了,但我也在调查这个并在网上找到了这个。显然,它是 类 的语法糖,带有类似网格的实例变量。
The Syntactic Sugar
These are all equivalent ways to get the bottom-left square:
board.grid[2][0] board.[](2, 0) board[2, 0] # syntactic sugar
The syntactic sugar allows us to call the Board#[] method with our arguments inside of the square brackets themselves rather than in parentheses following the square brackets.
Similarly, the following are equivalent ways to set the top-right square:
board.grid[0][2] = :x board.[]=(0, 2, :x) board[0, 2] = :x # syntactic sugar
Naturally, if we bother to set up the special [] and []= methods, we'll use the syntactic sugar way. :)
可以从这里找到更多信息 link:
https://github.com/emgreen33/Practice/blob/master/W2D4/bracket-methods.md