如何在没有运行时的情况下修改 Ruby 中的符号错误:无法修改冻结的符号?



如果位置符合给定条件,我正在尝试更改棋子的颜色,但是不断收到以下错误消息:

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"}

国际象棋.rb 文件颜色

21. class Symbol
22. def color
23. return @color unless @color.nil?
24. @color = :a < self ? :black : :white
25.
26. end

国际象棋.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

国际象棋.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 中,符号的实例旨在用作常量或不可变值。因此,符号始终被冻结。

:a.frozen? #=> true

Object#freeze文档对冻结对象进行了以下说明:

冻结→

防止对obj的进一步修改。如果尝试修改,将引发RuntimeError。没有办法解冻冻结的物体。另请参阅Object#frozen?

此方法返回 self。

a = [ "a", "b", "c" ]
a.freeze
a << "z"

生产:

prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
from prog.rb:3

以下类的对象始终被冻结:整数、浮点数、符号。

这意味着将在以下行引发错误:

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

最新更新