Ruby 为什么不是';puts方法调用my.to\s方法时失败了吗?
我认为为自定义类定义Ruby 为什么不是';puts方法调用my.to\s方法时失败了吗?,ruby,puts,Ruby,Puts,我认为为自定义类定义to_s方法意味着对该类调用put方法将返回to_s指定的输出。然而,在这个程序中,我只有在编写put bingo\u board.to\s时才能得到我渴望的结果。发生了什么事 class BingoBoard < Array @@letters = %w[B I N G O] def initialize # populates an 5x5 array with numbers 1-100 # to make this accessible
to_s
方法意味着对该类调用put
方法将返回to_s
指定的输出。然而,在这个程序中,我只有在编写put bingo\u board.to\s
时才能得到我渴望的结果。发生了什么事
class BingoBoard < Array
@@letters = %w[B I N G O]
def initialize
# populates an 5x5 array with numbers 1-100
# to make this accessible across your methods within this class, I made
# this an instance variable. @ = instance variable
@bingo_board = Array.new(5) {Array.new(5)}
@bingo_board.each_with_index do |column, i|
rangemin = 15 * i + 1
@bingo_board[i] = (rangemin..(rangemin+14)).to_a.sample(5)
end
@bingo_board[2][2] = "X" # the 'free space' in the middle
@game_over = false
end
def game_over?
@game_over
end
def generate_call
....
end
def compare_call(call)
@bingo_board[@@letters.index(call[0])].include? call[1]
end
def react_to_call(call)
...
end
def check_board
...
end
def show_column(num)
...
end
def to_s
result = ""
0.upto(4) do |val|
result += " " + @@letters[val] + " "
end
result += "\n\n"
0.upto(4) do |row|
0.upto(4) do |col|
val = @bingo_board[col][row]
result += " " if val.to_i < 10
result += val.to_s + " "
end
result += "\n"
end
result
end
end
my_board = BingoBoard.new
counter = 0
until my_board.game_over?
puts my_board.to_s # renders the board in accordance with my to_s method
call = my_board.generate_call
counter += 1
puts "\nThe call \# #{counter} is #{call[0]} #{call[1]}"
my_board.react_to_call(call)
gets.chomp
end
puts my_board # renders bubkes (i.e., nothing)
puts "\n\n"
puts "Game over"
class BingoBoard
看起来它运行的是Array#inspect
方法,而不是自定义的方法。将别名\u方法:inspect,:to \u s
添加到to \u s
定义结束后,将对您有所帮助
但是它只适用于p
,因为放置运行每个(&:inspect)
这是因为您正在从数组扩展。这就是为什么你会有古怪的行为。我看不出您需要从哪里扩展,所以只要删除它,事情就会如您所期望的那样工作
如果你想知道为什么会发生这种情况,这里有一个更详细的答案。基本上,puts对数组做了一个例外,所以当数组被传递时,puts被调用到每个成员上 如果对象是数组
或可以转换为数组(即它实现到_-ary
),则放置
不会调用对象上的到_-s
,而是通过调用对象上的到_-s
在对象上迭代并打印其中的每个对象
见:
,虽然有些含蓄:
如果使用数组参数调用,则将每个元素写入新行
正如@jörgwmittag所说,这是一个特例。该方法以不同的方式处理数组,即对进行响应的任何数组。它首先调用到_-ary
,然后对结果数组的每个元素进行迭代,并且只对它们调用。它从不对数组本身调用
如果您委托给一个成员数组,而不是从数组
中进行子类化,那么您可以对“继承”(委托)的内容进行更细粒度的控制。然后,您可以从委托中排除到_ary
,这将阻止put
将对象视为数组并触发此行为
其他一般解决方案:
使用字符串插值或显式调用
,以便放入
接收的内容已经是字符串:
puts "#{bingo_board}"
puts bingo_board.to_s
使用print
或printf
代替put
:
print bingo_board,"\n"
printf "%s\n",bingo_board
好啊现在,我得到的不是纯正的bubkes,而是[]哇!这是一个快速解决方案。但是数组有它自己的方法。为什么我的自定义方法不能覆盖它,@jwater?tl;你留给我的链接的博士:数组被区别对待,没有人真正知道为什么。这是一个公平的总结吗?另外:那么说数组to_s方法不能被覆盖是否准确?@pgblu-不准确,它被覆盖了,如果你使用其他方法,比如说,print,它会调用你的to_s,但只要你使用put方法,那么你是对的。
print bingo_board,"\n"
printf "%s\n",bingo_board