2 votes

Différence entre puts a et puts "#{a}".

Je pensais que faire puts #{a} donnerait le même résultat que puts a mais il s'est avéré que ce n'était pas le cas. Pensez-y :

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>

Dans l'exemple ci-dessus, cela n'a pas beaucoup d'importance, mais cela peut en avoir lorsque je veux imprimer plusieurs variables sur une ligne, comme (psudocode) :

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

Pourquoi la sortie est-elle différente ici ? Font-ils réellement des choses différentes, ou ont-ils une sémantique différente ?

6voto

DigitalRoss Points 80400

C'est parce que "#{a}" appelle le #to_s sur l'expression.

Donc :

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

Mise à jour :

Pour élaborer, puts appelle éventuellement #to_s mais il ajoute une logique en amont de la sortie réelle, y compris une gestion spéciale des tableaux. Il se trouve que Array#to_s n'utilise pas le même algorithme. (Voir puts docs ici). Voici exactement ce qu'il fait...

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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X