ruby - 替换 Ruby 中的 to_s 方法。没有打印出想要的字符串

标签 ruby class

因此,我刚刚开始学习 Ruby,我在我的类中包含了一个 to_s 方法,这样我就可以简单地将对象传递给 puts 方法,并让它返回的不仅仅是对象 ID。我犯了一个错误并将其定义为:

def to_s
    puts "I'm #{@name} with a health of #{@health}."
end

代替:

def to_s
    "I'm #{@name} with a health of #{@health}."
end

因此,当我在使用第一个代码块时执行此操作时:

player1 = Player.new("larry")
puts player1

当我执行以上两行代码时,我得到了一个对象 ID 和一个字符串,而不仅仅是字符串。为什么是这样?我得到这个输出:

I'm Larry with a health of 90.
#<Player:0x007fca1c08b270>

我正在思考为什么程序的第一个版本不只是将字符串打印到控制台,而是返回对象 ID 和字符串。我认为当我将对象传递给 puts 时,所有发生的事情就是 puts 转过来并调用 to_s 方法来获取播放器的字符串表示形式。对吧?

最佳答案

当给定的参数不是字符串或数组时,puts 调用 rb_obj_as_string 将其参数转换为字符串(参见 rb_io_puts)

如果您通过 ruby​​ 代码库搜索 rb_obj_as_string(我发现 http://rxr.whitequark.org 对此很有用),您可以看到它是 defined as

VALUE rb_obj_as_string(VALUE obj)
{
  VALUE str;

  if (RB_TYPE_P(obj, T_STRING)) {
    return obj;
  }
  str = rb_funcall(obj, id_to_s, 0);
  if (!RB_TYPE_P(str, T_STRING))
    return rb_any_to_s(obj);
  if (OBJ_TAINTED(obj)) OBJ_TAINT(str);
  return str;
}

简而言之:

  • 如果参数已经是字符串则直接返回
  • 调用 to_s
  • 如果结果不是字符串,调用 rb_any_to_s 并返回它。

rb_any_to_s 是实现您看到的默认“类名和 id”结果的:对于任何对象,它返回 #<ClassName: 0x1234567890abcdef> 形式的字符串

回到您的代码,当您运行 puts player1 时,它​​会调用 rb_obj_as_string 将您的播放器转换为字符串。

这首先调用您的 to_s 方法,该方法使用 puts 输出您的消息。然后您的方法返回 nil(因为那是 puts 总是返回的)所以 ruby​​ 调用 rb_any_to_s ,这就是最外层的 puts 最终使用的。

关于ruby - 替换 Ruby 中的 to_s 方法。没有打印出想要的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26365410/

相关文章:

java api来运行Windows批处理程序?

python - 根据类 python 2.7 中的变量按字母顺序对类列表进行排序

ruby-on-rails - 在一行代码中初始化和递增变量

ruby - 列出另一个 Controller 中的一个对象

ruby - 让 RGeo GEOS 支持在部署到 Dokku 的 Rails 应用程序中工作

html - 如何打破CSS中父元素类的继承?

java - 如何为循环中的对象提供新名称?

ruby-on-rails - 获取错误 Apple 推送通知 OpenSSL::SSL::SSLError

ruby - 在 Ruby ElasticSearch 客户端中设置法拉第超时

java - 可用的私有(private)变量