Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么不是';puts方法调用my.to\s方法时失败了吗?_Ruby_Puts - Fatal编程技术网

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