更换Ruby中的to_s方法。不打印所需的字符串 [英] Replacing the to_s method in Ruby. Not printing out desired string

查看:435
本文介绍了更换Ruby中的to_s方法。不打印所需的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  def to_s 
输入I'm#{@ name}健康度为#{@ health}。
end

而不是:

  def to_s 
我是#{@ name},运行状况为#{@ health}。
end

所以,当我使用第一个代码块时:

  player1 = Player.new(larry)
put player1
pre>

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

 我是Larry,健康状态为90. 
#< Player:0x007fca1c08​​b270>

我想想为什么第一个版本的程序不只是打印出字符串到控制台,而是返回对象ID和字符串。我想,当我把对象传递给puts,所有发生的是,puts转向,并调用to_s方法来获取玩家的字符串表示。当给定的参数不是字符串或数组时

解决方案

调用 rb_obj_as_string 将其参数转换为字符串(参见 http://rxr.whitequark.org 对此有用),您可以看到它定义

  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结果:对于任何对象,它返回一个形式的字符串



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



code> to_s 方法,它使用 puts 输出消息。你的方法然后返回nil(因为这是总是返回)所以ruby调用 rb_any_to_s puts 结束使用。


So, I am just beginning to learn Ruby and I included a to_s method in my Class so that I can simply pass the Object to a puts method and have it return more than just the Object ID. I made a mistake and defined it as such:

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

instead of:

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

So, when I do this while using the first code block:

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

I get an object ID and a string when I execute the above two lines of code and not just the string. Why is this? I get this output:

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

I am trying to think about why the first version of the program doesn't just print out the string to console, but instead returns the object ID and the string. I thought that when I pass the object to puts, all that is happening is that puts turns around and calls the to_s method to get the player's string representation. Right?

解决方案

When given arguments that are not strings or arrays puts calls rb_obj_as_string to turn its arguments into strings (see rb_io_puts)

If you search for rb_obj_as_string through the ruby codebase (I find http://rxr.whitequark.org useful for this) you can see it's 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;
}

In brief this:

  • returns straightaway if the argument is already a string
  • calls to_s
  • if the result is not a string, call rb_any_to_s and return that.

rb_any_to_s is what implements the default "class name and id" result that you're seeing: for any object it returns a string of the form #<ClassName: 0x1234567890abcdef>

Returning to your code, when you run puts player1 it calls rb_obj_as_string to convert your player to a string.

This first calls your to_s method, which uses puts to output your message. Your method then returns nil (because that's what puts always returns) so ruby calls rb_any_to_s, and that is what the outermost puts ends up using.

这篇关于更换Ruby中的to_s方法。不打印所需的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆