Можно ли вызвать переопределенный to_s в классе в ruby? - PullRequest
0 голосов
/ 02 декабря 2018

После внесения изменений в одну из переменных в классе я хочу, чтобы реализованный мной метод класса 'string (to_s) вызывался с новым значением для вышеупомянутой переменной.В настоящее время я использую:

class Car
   ...
   def ask_for_color_change(string)
     normalize = string.downcase
      if normalize == "yes"
        color = gets.chomp
        self.set_color(color)
        # tried with self.to_s also, doesn't work
        puts self
      elsif normalize == "no"
        puts "happy you like your factory color -> #{@color}"
      else
        puts "please reply with either yes/no ONLY"
      end
    end

  def to_s
    puts "New Car Details"
    puts "---------------"
    puts "Make: #{@make}"
    puts "Model: #{@model}"
    puts "Color: #{@color}"
  end

end

puts self в вышеприведенном методе выводит #<Car:0x00007fabd18ddc98>.Из того, что я знаю, это реализация по умолчанию to_s.Итак, другими словами, как я могу назвать переопределенный to_s внутри самого класса?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

В мире уже слишком много хаоса, чтобы позволить кому-то решить, что его класс не возвращает строку, когда вы звоните to_s.Интерпретатор применяет это, вызывая Object#to_s вместо этого, если ваша реализация возвращает не строковую (или испорченную строку).

Из исходного кода, отредактированного для удобства чтения:

VALUE rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
    /* ... */

    for (i=0; i<argc; i++) {
        /* ... */
        line = rb_obj_as_string(argv[i]);
        /* outputting line here... */
    }

    return Qnil;
}

VALUE rb_obj_as_string(VALUE obj)
{
    VALUE str;

    // if obj is already a String, return it
    if (RB_TYPE_P(obj, T_STRING)) {
        return obj;
    }
    // call obj.to_s
    str = rb_funcall(obj, idTo_s, 0);
    // ensure it is a string
    return rb_obj_as_string_result(str, obj);
}

VALUE rb_obj_as_string_result(VALUE str, VALUE obj)
{
    // if str isn't a String use Object#to_s
    if (!RB_TYPE_P(str, T_STRING)) return rb_any_to_s(obj);
    /* ... */
    return str;
}
0 голосов
/ 02 декабря 2018

Теперь я могу неявно вызывать to_s в методе ask_for_color_change(string) путем рефакторинга кода to_s следующим образом:

def to_s
  "
  New Car Details
  --------------- 
  Make: #{@make}
  Model: #{@model}
  Color: #{@color}
  "
end

Итак, это было связано со способом puts реализовано.Будем весьма благодарны за комментарии относительно способности метода puts по-прежнему видеть реализацию по умолчанию.Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...