Стандартный (идиоматический) способ преобразования объекта в строку

Я попытался напечатать объект этого класса:

define class <bill> (<object>)
    slot num :: <string>;
    slot ref :: <string>;
end class <bill>;

Я могу сделать метод, как say

define method say (bill : <bill>) => ();
    format-out("num:%s\n", bill.num);
    format-out("ref:%s\n", bill.ref);
end method say;

но я хочу метод для преобразования объекта в <string> что можно использовать как

format-out("%s\n", bill);

or

format-out("%s\n", as(<string>, bill));

or

format-out("%=\n", bill);

Я старался

define method as(type == <string>, bill :: <bill>) 
  => (s :: <string>);
  let result :: <stretchy-vector> = make(<stretchy-vector>);
  add!(result, bill.num);
  add!(result, bill.ref);
  join(result, " ");
end method as;

но с:

format-out("\%s\n", as(<string>,bill)); 

У меня был такой результат

Object {<bill>} cannot be converted to class {<class>: <string>}
Object {<bill> 0x1ff8180} cannot be converted to class {class <string> 0x7f5d5c645c00}
Breaking into debugger.
Trace/breakpoint trap

С этим:

format-out("%s\n", bill);

этот результат:

{<bill> #x00000000025EF1B0}

Что я делаю не так? Каков стандартный (идиоматический) способ печати объекта?

1 ответ

Решение

Идиоматический способ добавить поддержку печати объекта - это специализация print-object. Но если вы хотите иметь возможность преобразовать объектное представление в строку, то, как и вы, нужно специализироваться на общем. Это работает здесь, так что, возможно, где-то есть ошибка:

module: bill

define class <bill> (<object>)
  constant slot num :: <string>, init-keyword: num:;
  constant slot ref :: <string>, init-keyword: ref:
end class <bill>;

define method as(type == <string>, bill :: <bill>) => (s :: <string>);
  join(vector(bill.num, bill.ref), " ");
end method as;

format-out("%=\n", as(<string>, make(<bill>, num: "1", ref: "a")));

Результат:

$ bill 
"1 a"
Другие вопросы по тегам