1

I tried to print an object of this class:

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

I can make a method like say

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

but I want a method to convert the object to <string> that can be used like

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

or

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

or

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

I tried

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;

but with:

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

I had this result

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

An with this:

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

that result:

{<bill> #x00000000025EF1B0}

What I'm doing wrong? What is the standard (idiomatic) way of printing an object?

fraya
  • 61
  • 4

1 Answers1

2

The idiomatic way to adding support for printing an object is by specializing print-object. But if you want to be able to convert object representation to string, specializing as generic is the way to go, as you did. It works here, so maybe there's a bug somewhere:

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")));

Result:

$ bill 
"1 a"
alf
  • 8,377
  • 24
  • 45
abeaumont
  • 36
  • 1