How can I modify a Symbol in Ruby without a RuntimeError: Can't modify frozen Symbol?
How can I modify a Symbol in Ruby without a RuntimeError: Can't modify frozen Symbol?
如果位置符合给定条件,我正在尝试更改棋子的颜色,但不断收到以下错误消息:
Position#move_str
Failure/Error: it {expect(Position[P: [e2, e3], p:[d3, d4]].move_str(e2,d3)).to eq "ed3"}
RuntimeError:
can't modify frozen Symbol
# ./chess.rb:24:in `color'
# ./chess.rb:122:in `block in move_str'
# ./chess.rb:122:in `select!'
# ./chess.rb:122:in `move_str'
# ./chess_spec.rb:75:in `block (3 levels) in <top (required)>'
我正在从一个单独的文件调用代码(该文件已正确链接,因为之前与其他部分的测试正在运行)。就是通过下面的代码片段运行
chess_spec.rb 文件:
75. it {expect(Position[P: e2, p:d3].move_str(e2,d3)).to eq "ed"}
76. it {expect(Position[P: [e2, e3], p:[d3, d4]].move_str(e2,d3)).to eq "ed3"}
chess.rb 文件颜色
21. class Symbol
22. def color
23. return @color unless @color.nil?
24. @color = :a < self ? :black : :white
25.
26. end
chess.rb 文件 move_str
113. def move_str(from, to)
114. piece = board[from]
115. piece_str = piece.pawn? ? "" : piece
116. list = find(piece, to)
117. is_capture = board[to] || piece.pawn? && to == ep
118. if piece.pawn? && is_capture then
119.
120. possible_pawn_pos = [*0..7].select{|row|board[from%10+(row+2)*10] == piece}
121. possible_pawn_pos.select! { |row| target = board[to%10 + (row+2+white(-1, 1))*10]; target && target.color != piece.color }
122. if possible_pawn_pos == 1 then"#{from.to_sq[0]}#{to.to_sq[0]}"
123. else
124. "#{from.to_sq[0]}#{to.to_sq}"
125. end
126. else
127. if list.size == 1 then
128. "#{piece_str}#{to.to_sq}"
129. elsif list.select { |idx| idx%10 == from%10}.size == 1
130. "#{piece_str}#{from.to_sq[0]}#{to.to_sq}"
131. elsif list.select { |idx| idx/10 == from/10}.size == 1
132. "#{piece_str}#{from.to_sq[1]}#{to.to_sq}"
133. else
134. "#{piece_str}#{from.to_sq}#{to.to_sq}"
135. end
136. end
137. end
chess.rb 文件白色
109. def white(w,b,t=turn)
110. t == :white ? w : b
111. end
我知道错误来自第 122 行,如错误消息中所述,并且相信它来自 (row+2+white(-1, 1))*10]
部分,尽管我对 Ruby 还不太确定。因为它是一个符号,我知道你根本不能 dup
它。
那我怎么才能改变符号的颜色呢?
提前感谢您的帮助,如果我在发布时犯了任何错误,我深表歉意,因为我是 Ruby 和堆栈溢出的新手。
在 Ruby 中,Symbol 的实例旨在用作常量或不可变值。由于这个原因,符号总是被冻结。
:a.frozen? #=> true
Object#freeze
documentation 关于冻结对象的说明如下:
freeze → obj
Prevents further modifications to obj. A RuntimeError
will be raised if modification is attempted. There is no way to unfreeze a frozen object. See also Object#frozen?
.
This method returns self.
a = [ "a", "b", "c" ]
a.freeze
a << "z"
produces:
prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
from prog.rb:3
Objects of the following classes are always frozen: Integer, Float, Symbol.
这意味着将在以下行中引发错误:
class Symbol
def color
return @color unless @color.nil?
@color = :a < self ? :black : :white
# ^ Instance variable can only be read, writing to it
# counts as modification, thus raising an exception.
end
end
如果位置符合给定条件,我正在尝试更改棋子的颜色,但不断收到以下错误消息:
Position#move_str
Failure/Error: it {expect(Position[P: [e2, e3], p:[d3, d4]].move_str(e2,d3)).to eq "ed3"}
RuntimeError:
can't modify frozen Symbol
# ./chess.rb:24:in `color'
# ./chess.rb:122:in `block in move_str'
# ./chess.rb:122:in `select!'
# ./chess.rb:122:in `move_str'
# ./chess_spec.rb:75:in `block (3 levels) in <top (required)>'
我正在从一个单独的文件调用代码(该文件已正确链接,因为之前与其他部分的测试正在运行)。就是通过下面的代码片段运行
chess_spec.rb 文件:
75. it {expect(Position[P: e2, p:d3].move_str(e2,d3)).to eq "ed"}
76. it {expect(Position[P: [e2, e3], p:[d3, d4]].move_str(e2,d3)).to eq "ed3"}
chess.rb 文件颜色
21. class Symbol
22. def color
23. return @color unless @color.nil?
24. @color = :a < self ? :black : :white
25.
26. end
chess.rb 文件 move_str
113. def move_str(from, to)
114. piece = board[from]
115. piece_str = piece.pawn? ? "" : piece
116. list = find(piece, to)
117. is_capture = board[to] || piece.pawn? && to == ep
118. if piece.pawn? && is_capture then
119.
120. possible_pawn_pos = [*0..7].select{|row|board[from%10+(row+2)*10] == piece}
121. possible_pawn_pos.select! { |row| target = board[to%10 + (row+2+white(-1, 1))*10]; target && target.color != piece.color }
122. if possible_pawn_pos == 1 then"#{from.to_sq[0]}#{to.to_sq[0]}"
123. else
124. "#{from.to_sq[0]}#{to.to_sq}"
125. end
126. else
127. if list.size == 1 then
128. "#{piece_str}#{to.to_sq}"
129. elsif list.select { |idx| idx%10 == from%10}.size == 1
130. "#{piece_str}#{from.to_sq[0]}#{to.to_sq}"
131. elsif list.select { |idx| idx/10 == from/10}.size == 1
132. "#{piece_str}#{from.to_sq[1]}#{to.to_sq}"
133. else
134. "#{piece_str}#{from.to_sq}#{to.to_sq}"
135. end
136. end
137. end
chess.rb 文件白色
109. def white(w,b,t=turn)
110. t == :white ? w : b
111. end
我知道错误来自第 122 行,如错误消息中所述,并且相信它来自 (row+2+white(-1, 1))*10]
部分,尽管我对 Ruby 还不太确定。因为它是一个符号,我知道你根本不能 dup
它。
那我怎么才能改变符号的颜色呢?
提前感谢您的帮助,如果我在发布时犯了任何错误,我深表歉意,因为我是 Ruby 和堆栈溢出的新手。
在 Ruby 中,Symbol 的实例旨在用作常量或不可变值。由于这个原因,符号总是被冻结。
:a.frozen? #=> true
Object#freeze
documentation 关于冻结对象的说明如下:
freeze → obj
Prevents further modifications to obj. A
RuntimeError
will be raised if modification is attempted. There is no way to unfreeze a frozen object. See alsoObject#frozen?
.This method returns self.
a = [ "a", "b", "c" ] a.freeze a << "z"
produces:
prog.rb:3:in `<<': can't modify frozen Array (FrozenError) from prog.rb:3
Objects of the following classes are always frozen: Integer, Float, Symbol.
这意味着将在以下行中引发错误:
class Symbol
def color
return @color unless @color.nil?
@color = :a < self ? :black : :white
# ^ Instance variable can only be read, writing to it
# counts as modification, thus raising an exception.
end
end