简体   繁体   English

放置a和放置“#{a}”之间的区别

[英]Difference between puts a and puts “#{a}”

I thought that doing puts #{a} would result in the same output as puts a , but found this not to be the case. 我认为执行puts #{a}会得到与puts a相同的输出,但事实并非如此。 Consider: 考虑:

irb(main):001:0> a = [1,2]
=> [1, 2]
irb(main):002:0> puts a
1
2
=> nil
irb(main):003:0> puts "#{a}"
12
=> nil
irb(main):004:0>

In the above example it doesn't matter much, but it may matter when I want to print multiple variables on one line, such as (psudocode): 在上面的示例中,这没什么大不了的,但是当我想在一行上打印多个变量时可能会很重要,例如(psudocode):

puts "There are #{a.size} items in the whitelist: #{a}"

Why is the output different here? 为什么这里的输出不同? Do they actually do different things, or have different semantics? 他们实际上是在做不同的事情,还是具有不同的语义?

That's because "#{a}" calls the #to_s method on the expression. 这是因为"#{a}"在表达式上调用了#to_s方法。

So: 所以:

puts a        # equivalent to, well, puts a
puts "#{a}"   # equivalent to the next line
puts a.to_s

Update: 更新:

To elaborate, puts eventually calls #to_s but it adds logic in front of the actual output, including special handling for arrays. 详细地说, puts最终调用#to_s但是它在实际输出之前添加了逻辑,包括对数组的特殊处理。 It just happens that Array#to_s doesn't use the same algorithm. 碰巧Array#to_s没有使用相同的算法。 (See puts docs here.) Here is exactly what it does... (请参阅此处的puts文档。)这正是它的作用...

rb_io_puts(int argc, VALUE *argv, VALUE out)
{
    int i;
    VALUE line;

    /* if no argument given, print newline. */
    if (argc == 0) {
        rb_io_write(out, rb_default_rs);
        return Qnil;
    }
    for (i=0; i<argc; i++) {
        if (TYPE(argv[i]) == T_STRING) {
            line = argv[i];
            goto string;
        }
        line = rb_check_array_type(argv[i]);
        if (!NIL_P(line)) {
            rb_exec_recursive(io_puts_ary, line, out);
            continue;
        }
        line = rb_obj_as_string(argv[i]);
      string:
        rb_io_write(out, line);
        if (RSTRING_LEN(line) == 0 ||
            !str_end_with_asciichar(line, '\n')) {
            rb_io_write(out, rb_default_rs);
        }
    }

    return Qnil;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM