<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -8,6 +8,7 @@ h4. 20090430 update
 * features:
 ** Type auto-convert[1]
 ** [] singleton method for ErlixTuple and ErlixList[2]
+** add ErlixTerm.to_s, remove ErlixTerm.puts
 
 h4. erlix-v0.3 changelog:
 
@@ -80,40 +81,29 @@ irb(main):004:0&gt; a2=ErlixAtom.new(&quot;atom2&quot;)
 irb(main):005:0&gt; f=ErlixFloat.new(17.0)
 =&gt; 17.000000
 irb(main):006:0&gt; b=ErlixBinary.new(&quot;data\0data&quot;)
-=&gt; #Binary&lt;&lt;...&gt;&gt;
-irb(main):007:0&gt; i=ErlixInt.new(101)
+=&gt; #Bin
+irb(main):007:0&gt; b.data
+=&gt; &quot;data\000data&quot;
+irb(main):008:0&gt; i=ErlixInt.new(101)
 =&gt; 101
-irb(main):008:0&gt; t=ErlixTuple.new([a1,f,b,a2,i])
-=&gt; #&lt;ErlixTuple:0xb7c37104&gt;
-irb(main):009:0&gt; t.puts
-{atom1,17.000000,#Bin,atom2,101}
-=&gt; nil
+irb(main):009:0&gt; t=ErlixTuple.new([a1,f,b,a2,i])
+=&gt; {atom1,17.000000,#Bin,atom2,101}
 irb(main):010:0&gt; list=ErlixList.new([a1,i,t])
-=&gt; #&lt;ErlixList:0xb7c26598&gt;
-irb(main):011:0&gt; list.puts
-[atom1,101,{atom1,17.000000,#Bin,atom2,101}]
-=&gt; nil
-irb(main):012:0&gt; t[2]
+=&gt; [atom1,101,{atom1,17.000000,#Bin,atom2,101}]
+irb(main):011:0&gt; t[2]
 =&gt; 17.000000
-irb(main):013:0&gt; t[2].class
+irb(main):012:0&gt; t[2].class
 =&gt; ErlixFloat
-irb(main):014:0&gt; t[3].class
+irb(main):013:0&gt; t[3].class
 =&gt; ErlixBinary
-irb(main):015:0&gt; t.nth(3)==t[3]
+irb(main):014:0&gt; t.nth(3)==t[3]
 =&gt; true
-irb(main):016:0&gt; list.head
+irb(main):015:0&gt; list.head
 =&gt; atom1
-irb(main):017:0&gt; list.tail.puts
-[101,{atom1,17.000000,#Bin,atom2,101}]
-=&gt; nil
-irb(main):018:0&gt; list2=list.cons(b)
-=&gt; #&lt;ErlixList:0xb7bfbed8&gt;
-irb(main):019:0&gt; list2.puts
-[#Bin,atom1,101,{atom1,17.000000,#Bin,atom2,101}]
-=&gt; nil
-irb(main):020:0&gt;
-irb(main):021:0&gt; b.data
-=&gt; &quot;data\000data&quot;
+irb(main):016:0&gt; list.tail
+=&gt;[101,{atom1,17.000000,#Bin,atom2,101}]
+irb(main):017:0&gt; list2=list.cons(b)
+=&gt; [#Bin,atom1,101,{atom1,17.000000,#Bin,atom2,101}]
 &lt;/code&gt;&lt;/pre&gt;
 
 &lt;a name=&quot;fn1&quot;&gt;Some Ruby-Type var can be auto-convert to particular Erlang-Type:&lt;/a&gt;
@@ -133,11 +123,8 @@ See below
 
 &lt;pre&gt;&lt;code&gt;
 irb(main):016:0&gt; c=ErlixList.new([&quot;string-to-list&quot;,1,:symbol_to_atom,1.00])
-=&gt; #&lt;ErlixList:0xb7bddb2c&gt;
-irb(main):017:0&gt; c.puts
-[&quot;string-to-list&quot;,1,symbol_to_atom,1.000000]
-=&gt; nil
-irb(main):018:0&gt; c.head.class
+=&gt; [&quot;string-to-list&quot;,1,symbol_to_atom,1.000000]
+irb(main):017:0&gt; c.head.class
 =&gt; ErlixList
 irb(main):019:0&gt;
 &lt;/code&gt;&lt;/pre&gt;
@@ -145,35 +132,30 @@ irb(main):019:0&gt;
 &lt;a name=&quot;fn2&quot;&gt;Use singleton method [] to create ErlixTuple/ErlixList&lt;/a&gt;
 &lt;pre&gt;&lt;code&gt;
 irb(main):019:0&gt; c=ErlixList[&quot;string-to-list&quot;,1,:symbol_to_atom,1.00]
-=&gt; #&lt;ErlixList:0xb7bd5c38&gt;
+=&gt; [&quot;string-to-list&quot;,1,symbol_to_atom,1.000000]
 irb(main):020:0&gt; t=ErlixTuple[&quot;string-to-list&quot;,1,:symbol_to_atom,1.00]
-=&gt; #&lt;ErlixTuple:0xb7bd079c&gt;
+=&gt; {&quot;string-to-list&quot;,1,symbol_to_atom,1.000000}
 irb(main):021:0&gt; t[1]
-=&gt; #&lt;ErlixList:0xb7bcd308&gt;
+=&gt; &quot;string-to-list&quot;
 irb(main):022:0&gt; t[3]
 =&gt; symbol_to_atom
+irb(main):023:0&gt; sl=%w[abc def xyz]
+=&gt; [&quot;abc&quot;, &quot;def&quot;, &quot;xyz&quot;]
+irb(main):024:0&gt; ErlixTuple[*sl]
+=&gt; {&quot;abc&quot;,&quot;def&quot;,&quot;xyz&quot;}
 &lt;/code&gt;&lt;/pre&gt;
 
 And we can use @match@ to test a ErlixTerm's format, use @mget@ to get a particular ErlixTerm inside a ErlixTerm:
 
 &lt;pre&gt;&lt;code&gt;
-irb(main):023:0&gt; list2.puts
-[#Bin,atom1,101,{atom1,17.000000,#Bin,atom2,101}]
-=&gt; nil
+irb(main):023:0&gt; list2
+=&gt; [#Bin,atom1,101,{atom1,17.000000,#Bin,atom2,101}]
 irb(main):024:0&gt; list2.match(&quot;[B,Atom,101,Tuple]&quot;)
 =&gt; true
 irb(main):025:0&gt; list2.match(&quot;[nomatch,B,Atom,101,Tuple]&quot;)
 =&gt; false
 irb(main):027:0&gt; t2=list2.mget(&quot;[B,Atom,101,Tuple]&quot;,&quot;Tuple&quot;)
-=&gt; #&lt;ErlixTuple:0xb7bdd9b0&gt;
-irb(main):028:0&gt; t2.puts
-{atom1,17.000000,#Bin,atom2,101}
-=&gt; nil
-irb(main):029:0&gt; a=%w[abc def xyz]
-=&gt; [&quot;abc&quot;, &quot;def&quot;, &quot;xyz&quot;]
-irb(main):039:0&gt; t=ErlixTuple[*a]
-=&gt; #&lt;ErlixTuple:0xb7c6b1ac&gt;
-
+=&gt; {atom1,17.000000,#Bin,atom2,101}
 &lt;/code&gt;&lt;/pre&gt;
 
 h3. Play with the Real-Erlang-Node
@@ -251,7 +233,7 @@ t=Thread.new{
     #in erlix-v0.2,erecv make this thread block,v0.3 fixed this
     m=c.erecv
     puts m.mtype
-    m.message.puts
+    puts m.message
     puts m.class
     puts m.from
     puts m.to</diff>
      <filename>README.textile</filename>
    </modified>
    <modified>
      <diff>@@ -9,4 +9,4 @@ File.chmod(0755,findei)
 ei_dir=`#{findei}`.chomp
 src_dir=File.join(File.dirname(__FILE__),&quot;src&quot;)
 mkmf=File.join(File.dirname(__FILE__),&quot;extconf.rb&quot;)
-puts `ruby #{mkmf} --with-ei-dir=#{ei_dir} --with-ldflags=\&quot;-lei -lerl_interface\&quot; --srcdir=#{src_dir}`
+puts `ruby #{mkmf} --with-ei-dir=#{ei_dir} --with-ldflags=\&quot;-lei -lerl_interface -lpthread\&quot; --srcdir=#{src_dir}`</diff>
      <filename>configure.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,12 +26,6 @@ VALUE erlix_atom_init(VALUE self,VALUE string){
 }
 
 
-VALUE erlix_atom_to_str(VALUE self){
-  ErlixTerm* atom;
-  Data_Get_Struct(self,ErlixTerm,atom);
-  return rb_str_new2(ERL_ATOM_PTR(atom-&gt;term));
-}
-
 VALUE erlix_atom_size(VALUE self){
   ErlixTerm *atom;
   Data_Get_Struct(self,ErlixTerm,atom);
@@ -48,7 +42,6 @@ void init_erlix_atom(){
 
   rb_define_alloc_func(erlix_cErlixAtom,erlix_atom_alloc);
   rb_define_method(erlix_cErlixAtom,&quot;initialize&quot;,erlix_atom_init,1);
-  rb_define_method(erlix_cErlixAtom,&quot;to_s&quot;,erlix_atom_to_str,0);
   rb_define_method(erlix_cErlixAtom,&quot;size&quot;,erlix_atom_size,0);
   rb_define_method(erlix_cErlixAtom,&quot;etype&quot;,erlix_atom_etype,0);
 </diff>
      <filename>src/erlix_atom.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_atom_alloc(VALUE klass);
 VALUE erlix_atom_init(VALUE self,VALUE string);
-VALUE erlix_atom_to_str(VALUE self);
 VALUE erlix_atom_size(VALUE self);
 VALUE erlix_atom_etype(VALUE self);
 </diff>
      <filename>src/erlix_atom.h</filename>
    </modified>
    <modified>
      <diff>@@ -26,10 +26,6 @@ VALUE erlix_binary_init(VALUE self,VALUE string){
 }
 
 
-VALUE erlix_binary_to_str(VALUE self){
-  return rb_str_new2(&quot;#Binary&lt;&lt;...&gt;&gt;&quot;);
-}
-
 VALUE erlix_binary_data(VALUE self){
   ErlixTerm* binary;
   Data_Get_Struct(self,ErlixTerm,binary);
@@ -52,7 +48,6 @@ void init_erlix_binary(){
 
   rb_define_alloc_func(erlix_cErlixBinary,erlix_binary_alloc);
   rb_define_method(erlix_cErlixBinary,&quot;initialize&quot;,erlix_binary_init,1);
-  rb_define_method(erlix_cErlixBinary,&quot;to_s&quot;,erlix_binary_to_str,0);
   rb_define_method(erlix_cErlixBinary,&quot;data&quot;,erlix_binary_data,0);
   rb_define_method(erlix_cErlixBinary,&quot;size&quot;,erlix_binary_size,0);
   rb_define_method(erlix_cErlixBinary,&quot;etype&quot;,erlix_binary_etype,0);</diff>
      <filename>src/erlix_binary.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_binary_alloc(VALUE klass);
 VALUE erlix_binary_init(VALUE self,VALUE string);
-VALUE erlix_binary_to_str(VALUE self);
 VALUE erlix_binary_data(VALUE self);
 VALUE erlix_binary_size(VALUE self);
 VALUE erlix_binary_etype(VALUE self);</diff>
      <filename>src/erlix_binary.h</filename>
    </modified>
    <modified>
      <diff>@@ -29,15 +29,6 @@ VALUE erlix_float_init(VALUE self,VALUE fix){
 }
 
 
-VALUE erlix_float_to_str(VALUE self){
-  ErlixTerm* efloat;
-  Data_Get_Struct(self,ErlixTerm,efloat);
-  char buf[12];
-  memset(buf,0,12);
-  sprintf(buf,&quot;%f&quot;,ERL_FLOAT_VALUE(efloat-&gt;term));
-  return rb_str_new2(buf);
-}
-
 VALUE erlix_float_to_fix(VALUE self){
   ErlixTerm *efloat;
   Data_Get_Struct(self,ErlixTerm,efloat);
@@ -54,7 +45,6 @@ void init_erlix_float(){
 
   rb_define_alloc_func(erlix_cErlixFloat,erlix_float_alloc);
   rb_define_method(erlix_cErlixFloat,&quot;initialize&quot;,erlix_float_init,1);
-  rb_define_method(erlix_cErlixFloat,&quot;to_s&quot;,erlix_float_to_str,0);
   rb_define_method(erlix_cErlixFloat,&quot;to_i&quot;,erlix_float_to_fix,0);
   rb_define_method(erlix_cErlixFloat,&quot;etype&quot;,erlix_float_etype,0);
 </diff>
      <filename>src/erlix_float.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_float_alloc(VALUE klass);
 VALUE erlix_float_init(VALUE self,VALUE fixnum);
-VALUE erlix_float_to_str(VALUE self);
 VALUE erlix_float_to_fix(VALUE self);
 VALUE erlix_float_size(VALUE self);
 VALUE erlix_float_etype(VALUE self);</diff>
      <filename>src/erlix_float.h</filename>
    </modified>
    <modified>
      <diff>@@ -29,15 +29,6 @@ VALUE erlix_int_init(VALUE self,VALUE fix){
 }
 
 
-VALUE erlix_int_to_str(VALUE self){
-  ErlixTerm* eint;
-  Data_Get_Struct(self,ErlixTerm,eint);
-  char buf[12];
-  memset(buf,0,12);
-  sprintf(buf,&quot;%d&quot;,ERL_INT_VALUE(eint-&gt;term));
-  return rb_str_new2(buf);
-}
-
 VALUE erlix_int_to_fix(VALUE self){
   ErlixTerm *eint;
   Data_Get_Struct(self,ErlixTerm,eint);
@@ -54,7 +45,6 @@ void init_erlix_int(){
 
   rb_define_alloc_func(erlix_cErlixInt,erlix_int_alloc);
   rb_define_method(erlix_cErlixInt,&quot;initialize&quot;,erlix_int_init,1);
-  rb_define_method(erlix_cErlixInt,&quot;to_s&quot;,erlix_int_to_str,0);
   rb_define_method(erlix_cErlixInt,&quot;to_i&quot;,erlix_int_to_fix,0);
   rb_define_method(erlix_cErlixInt,&quot;etype&quot;,erlix_int_etype,0);
 </diff>
      <filename>src/erlix_int.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_int_alloc(VALUE klass);
 VALUE erlix_int_init(VALUE self,VALUE fixnum);
-VALUE erlix_int_to_str(VALUE self);
 VALUE erlix_int_to_fix(VALUE self);
 VALUE erlix_int_size(VALUE self);
 VALUE erlix_int_etype(VALUE self);</diff>
      <filename>src/erlix_int.h</filename>
    </modified>
    <modified>
      <diff>@@ -48,9 +48,9 @@ VALUE erlix_list_init(VALUE self,VALUE ary){
         }
       }
       list-&gt;term=erl_mk_list(les,RARRAY(ary)-&gt;len);
-      for(i=0;i&lt;RARRAY(ary)-&gt;len;i++){
-        erl_free_term(*(les+i));
-      }
+      //for(i=0;i&lt;RARRAY(ary)-&gt;len;i++){
+      //  erl_free_term(*(les+i));
+      //}
       free(les);
     }
   }else if(TYPE(ary)==T_STRING){
@@ -85,17 +85,14 @@ VALUE erlix_list_create(int argc,VALUE *argv,VALUE klass){
       }
     }
     rterm=erl_mk_list(les,argc);
-    for(i=0;i&lt;argc;i++){
-      erl_free_term(*(les+i));
-    }
+    //for(i=0;i&lt;argc;i++){
+    //  erl_free_term(*(les+i));
+    //}
     free(les);
   }
   return erlix_term(rterm);
 }
 
-//TODO
-VALUE erlix_list_to_str(VALUE self);
-//TODO
 VALUE erlix_list_to_ary(VALUE self){
   ErlixTerm *list;
   Data_Get_Struct(self,ErlixTerm,list);
@@ -105,10 +102,13 @@ VALUE erlix_list_to_ary(VALUE self){
   int i=0;
   while(!ERL_IS_EMPTY_LIST(ep)){
     hd=erl_hd(ep);
-    rb_ary_store(ret,i,erlix_term(hd));
+    rb_ary_store(ret,i,erlix_term(erl_copy_term(hd)));
     tmp=erl_tl(ep);
-    if(ep!=list-&gt;term)erl_free_term(ep);
+    //if(ep!=list-&gt;term)erl_free_term(ep);
     ep=tmp;
+    //if(ERL_IS_EMPTY_LIST(ep)){
+    //  erl_free_term(ep);
+    //}
     ++i;
   }
   return ret;
@@ -117,28 +117,41 @@ VALUE erlix_list_to_ary(VALUE self){
 VALUE erlix_list_head(VALUE self){
   ErlixTerm *list;
   Data_Get_Struct(self,ErlixTerm,list);
+  if(ERL_IS_EMPTY_LIST(list-&gt;term)){
+    return Qnil;
+  }
   ETERM *ep=erl_hd(list-&gt;term);
-  return erlix_term(ep);
+  return erlix_term(erl_copy_term(ep));
 }
 
 VALUE erlix_list_tail(VALUE self){
   ErlixTerm *list;
   Data_Get_Struct(self,ErlixTerm,list);
-
+  if(ERL_IS_EMPTY_LIST(list-&gt;term)){
+    return Qnil;
+  }
   ETERM *ep=erl_tl(list-&gt;term);
-  return erlix_term(ep);
+  return erlix_term(erl_copy_term(ep));
 }
 
 VALUE erlix_list_cons(VALUE self,VALUE head){
-  if(!IS_ETERM(head)){
-    rb_raise(rb_eTypeError,&quot;the head must be ErlixTerm!&quot;);
+  if(!IS_ETERM(head) &amp;&amp; !CAN_AUTO_CONV(head)){
+    rb_raise(rb_eTypeError,&quot;the head must be ErlixTerm or Auto-Convertable-Type!&quot;);
     return Qnil;
   }
-  ErlixTerm *list,*hd;
+  ErlixTerm *list;
+  ETERM *ep;
   Data_Get_Struct(self,ErlixTerm,list);
-  Data_Get_Struct(head,ErlixTerm,hd);
-  ETERM *ep=erl_cons(hd-&gt;term,list-&gt;term);
-  return erlix_term(ep);
+  if(IS_ETERM(head)){
+    ErlixTerm *hd;
+    Data_Get_Struct(head,ErlixTerm,hd);
+    ep=erl_cons(hd-&gt;term,list-&gt;term);
+  }else{
+    ep=erl_cons(erlix_auto_conv(head),list-&gt;term);
+  }
+  VALUE ret= erlix_term(erl_copy_term(ep));
+  erl_free_term(ep);
+  return ret;
 }
 
 VALUE erlix_list_size(VALUE self){</diff>
      <filename>src/erlix_list.c</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,6 @@ VALUE erlix_list_create(int argc,VALUE *argv,VALUE klass);
 VALUE erlix_list_head(VALUE self);
 VALUE erlix_list_tail(VALUE self);
 VALUE erlix_list_cons(VALUE self,VALUE head);
-VALUE erlix_list_to_str(VALUE self);
 VALUE erlix_list_size(VALUE self);
 VALUE erlix_list_etype(VALUE self);
 </diff>
      <filename>src/erlix_list.h</filename>
    </modified>
    <modified>
      <diff>@@ -42,17 +42,6 @@ VALUE erlix_pid_init(VALUE self,VALUE econn){
 }
 
 
-VALUE erlix_pid_to_str(VALUE self){
-  ErlixTerm* pid;
-  Data_Get_Struct(self,ErlixTerm,pid);
-  char name[10];
-  ETERM *p=pid-&gt;term;
-  memset(name,0,10);
-  sprintf(name,&quot;&lt;%d.%d.%d&gt;&quot;,ERL_PID_NUMBER(p),ERL_PID_SERIAL(p),ERL_PID_CREATION(p));
-  return rb_str_new2(name);
-}
-
-
 VALUE erlix_pid_etype(VALUE self){
   return rb_str_new2(&quot;pid&quot;);
 }
@@ -62,7 +51,6 @@ void init_erlix_pid(){
 
   rb_define_alloc_func(erlix_cErlixPid,erlix_pid_alloc);
   rb_define_method(erlix_cErlixPid,&quot;initialize&quot;,erlix_pid_init,1);
-  rb_define_method(erlix_cErlixPid,&quot;to_s&quot;,erlix_pid_to_str,0);
   rb_define_method(erlix_cErlixPid,&quot;etype&quot;,erlix_pid_etype,0);
 
   rb_include_module(erlix_cErlixPid,erlix_mErlixTerm);</diff>
      <filename>src/erlix_pid.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_pid_alloc(VALUE klass);
 VALUE erlix_pid_init(VALUE self,VALUE econn);
-VALUE erlix_pid_to_str(VALUE self);
 VALUE erlix_pid_size(VALUE self);
 VALUE erlix_pid_etype(VALUE self);
 </diff>
      <filename>src/erlix_pid.h</filename>
    </modified>
    <modified>
      <diff>@@ -32,16 +32,6 @@ VALUE erlix_ref_init(VALUE self){
 }
 
 
-VALUE erlix_ref_to_str(VALUE self){
-  ErlixTerm* eref;
-  Data_Get_Struct(self,ErlixTerm,eref);
-  //char buf[64];
-  //memset(buf,0,12);
-  //sprintf(buf,&quot;#Ref&lt;%d.%d.%d.%d&gt;&quot;,ERL_REF_VALUE(eref-&gt;term));
-  return rb_str_new2(&quot;#Ref&lt;...&gt;&quot;);
-}
-
-
 VALUE erlix_ref_etype(VALUE self){
   return rb_str_new2(&quot;ref&quot;);
 }
@@ -51,7 +41,6 @@ void init_erlix_ref(){
 
   rb_define_alloc_func(erlix_cErlixRef,erlix_ref_alloc);
   rb_define_method(erlix_cErlixRef,&quot;initialize&quot;,erlix_ref_init,0);
-  rb_define_method(erlix_cErlixRef,&quot;to_s&quot;,erlix_ref_to_str,0);
   rb_define_method(erlix_cErlixRef,&quot;etype&quot;,erlix_ref_etype,0);
 
   rb_include_module(erlix_cErlixRef,erlix_mErlixTerm);</diff>
      <filename>src/erlix_ref.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_REF_alloc(VALUE klass);
 VALUE erlix_REF_init(VALUE self);
-VALUE erlix_REF_to_str(VALUE self);
 VALUE erlix_REF_etype(VALUE self);
 
 void init_erlix_REF();</diff>
      <filename>src/erlix_ref.h</filename>
    </modified>
    <modified>
      <diff>@@ -43,13 +43,171 @@ VALUE erlix_term_init_copy(VALUE copy,VALUE orig){
   return copy;
 }
 
-//obj.puts
-VALUE erlix_term_puts(VALUE self){
+
+//obj.to_s
+static void fill_string(VALUE *str,ETERM *ep);
+VALUE erlix_term_to_str(VALUE self){
   ErlixTerm *eterm;
   Data_Get_Struct(self,ErlixTerm,eterm);
-  erl_print_term(stdout,eterm-&gt;term);
-  printf(&quot;\n&quot;);
-  return Qnil;
+  ETERM *ep=eterm-&gt;term;
+  VALUE ret=rb_str_new2(&quot;&quot;);
+  fill_string(&amp;ret,ep);
+  return ret;
+}
+
+static int is_printable_list(const ETERM* term)
+{
+  while (ERL_TYPE(term) == ERL_LIST) {
+    ETERM* head = (ETERM*)(ERL_CONS_HEAD(term));
+    if (ERL_INT_VALUE(head)&lt;0 || ERL_INT_VALUE(head)&gt;255) {
+      return 0;
+    }
+    if (ERL_INT_VALUE(head) &lt; ' ') {
+      switch (ERL_INT_VALUE(head)) {
+      case '\n':
+      case '\r':
+      case '\t':
+      case '\v':
+      case '\b':
+      case '\f':
+        break;
+      default:
+        return 0;
+      }
+    }
+    term = (ETERM*)(ERL_CONS_TAIL(term));
+  }
+  return ERL_IS_EMPTY_LIST(term);
+}
+
+static void fill_printable_list(VALUE *str, const ETERM* ep){
+  ID concat=rb_intern(&quot;concat&quot;);
+  rb_funcall(*str,concat,1,rb_str_new2(&quot;\&quot;&quot;));
+  while (ERL_IS_CONS(ep)) {
+    int c = ERL_INT_VALUE((ETERM*)ERL_CONS_HEAD(ep));
+    if (c &gt;= ' ') {
+      char tmp_buf[2];
+      tmp_buf[0]=c;
+      tmp_buf[1]=0;
+      rb_funcall(*str,concat,1,rb_str_new2(tmp_buf));
+    }
+    else {
+      if(c=='\n'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\n&quot;));
+      }else if(c=='\r'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\r&quot;));
+      }else if(c=='\t'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\t&quot;));
+      }else if(c=='\v'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\v&quot;));
+      }else if(c=='\b'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\b&quot;));
+      }else if(c=='\f'){
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;\\f&quot;));
+      }else{
+        char tmp_buf[8];
+        memset(tmp_buf,0,8);
+        sprintf(tmp_buf,&quot;\\%o&quot;,c);
+        rb_funcall(*str,concat,1,rb_str_new2(tmp_buf));
+      }
+    }
+    ep = (ETERM*)ERL_CONS_TAIL(ep);
+  }
+  rb_funcall(*str,concat,1,rb_str_new2(&quot;\&quot;&quot;));
+}
+
+
+static void fill_string(VALUE *str,ETERM *ep){
+  ID concat=rb_intern(&quot;concat&quot;);
+
+  int j,i,doquote;
+  if (!ep) return;
+
+  j = i = doquote = 0;
+
+  if(ERL_IS_ATOM(ep)){
+    /* FIXME: what if some weird locale is in use? */
+    if (!islower((int)ERL_ATOM_PTR(ep)[0]))
+      doquote = 1;
+    for (i = 0; !doquote &amp;&amp; i &lt; ERL_ATOM_SIZE(ep); i++){
+      doquote = !(isalnum((int)ERL_ATOM_PTR(ep)[i])
+                  || (ERL_ATOM_PTR(ep)[i] == '_'));
+    }
+    if (doquote) {
+      rb_funcall(*str,concat,1,rb_str_new2(&quot;\'&quot;));
+    }
+    rb_funcall(*str,concat,1,rb_str_new2(ERL_ATOM_PTR(ep)));
+    if(doquote){
+      rb_funcall(*str,concat,1,rb_str_new2(&quot;\'&quot;));
+    }
+  }else if(ERL_IS_PID(ep)){
+    char tmp_buf_pid[24];
+    memset(tmp_buf_pid,0,24);
+    sprintf(tmp_buf_pid,&quot;&lt;%s.%d.%d&gt;&quot;,ERL_PID_NODE(ep),ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep));
+    rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_pid));
+  }else if(ERL_IS_PORT(ep)){
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;#Port&quot;));
+  }else if(ERL_IS_REF(ep)){
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;#Ref&quot;));
+  }else if(ERL_IS_EMPTY_LIST(ep)){
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;[]&quot;));
+  }else if(ERL_IS_LIST(ep)){
+    if (is_printable_list(ep)) {
+      fill_printable_list(str,ep);
+    } else {
+      rb_funcall(*str,concat,1,rb_str_new2(&quot;[&quot;));
+      ETERM *tl=ep,*hd,*tmp;
+      while (ERL_IS_CONS(tl)){
+        hd=erl_hd(tl);
+        fill_string(str,hd);
+        //erl_free_term(hd);
+        tmp = erl_tl(tl);
+        //if(tl!=ep)erl_free_term(tl);
+        tl=tmp;
+        if (ERL_IS_CONS(tl)) {
+          rb_funcall(*str,concat,1,rb_str_new2(&quot;,&quot;));
+        }
+      }
+      if (!ERL_IS_EMPTY_LIST(tl)) {
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;|&quot;));
+        fill_string(str, tl);
+      }else{
+        //erl_free_term(tl);
+      }
+      rb_funcall(*str,concat,1,rb_str_new2(&quot;]&quot;));
+    }
+  }else if(ERL_IS_TUPLE(ep)){
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;{&quot;));
+    for (i=0; i &lt; ERL_TUPLE_SIZE(ep); i++) {
+      ETERM *e=erl_element(i+1,ep);
+      fill_string(str,e);
+      //erl_free_term(e);
+      if (i != ERL_TUPLE_SIZE(ep)-1) {
+        rb_funcall(*str,concat,1,rb_str_new2(&quot;,&quot;));
+      }
+    }
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;}&quot;));
+  }else if(ERL_IS_BINARY(ep)){
+      rb_funcall(*str,concat,1,rb_str_new2(&quot;#Bin&quot;));
+  }else if(ERL_IS_INTEGER(ep)){
+      char tmp_buf_num[24];
+      memset(tmp_buf_num,0,24);
+      sprintf(tmp_buf_num,&quot;%d&quot;, ERL_INT_VALUE(ep));
+      rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_num));
+  }else if(ERL_IS_UNSIGNED_INTEGER(ep)){
+    char tmp_buf_unum[24];
+    memset(tmp_buf_unum,0,24);
+    sprintf(tmp_buf_unum,&quot;%u&quot;, ERL_INT_UVALUE(ep));
+    rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_unum));
+  }else if(ERL_IS_FLOAT(ep)){
+    char tmp_buf_float[24];
+    memset(tmp_buf_float,0,24);
+    sprintf(tmp_buf_float,&quot;%f&quot;, ERL_FLOAT_VALUE(ep));
+    rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_float));
+  }else{
+    rb_funcall(*str,concat,1,rb_str_new2(&quot;*Unknow*&quot;));
+    //rb_raise(rb_eException,&quot;ErlixTerm.to_s: Bad type of term !&quot;);
+  }
 }
 
 VALUE erlix_term_eql(VALUE left,VALUE right){
@@ -185,6 +343,7 @@ VALUE erlix_term(ETERM *term){
     eterm-&gt;term=term;
     return ret;
   }else{
+    rb_raise(rb_eException,&quot;Unknow Erlang Type!&quot;);
     //TODO OTHER TYPE!!!
     return Qnil;
   }
@@ -195,8 +354,8 @@ void init_erlix_term(){
   erlix_mErlixTerm=rb_define_module(&quot;ErlixTerm&quot;);
   rb_define_method(erlix_mErlixTerm,&quot;initialize_copy&quot;,erlix_term_init_copy,1);
   rb_define_method(erlix_mErlixTerm,&quot;eql?&quot;,erlix_term_eql,1);
+  rb_define_method(erlix_mErlixTerm,&quot;to_s&quot;,erlix_term_to_str,0);
   rb_define_method(erlix_mErlixTerm,&quot;match&quot;,erlix_term_match,1);
   rb_define_method(erlix_mErlixTerm,&quot;mget&quot;,erlix_term_mget,2);
-  rb_define_method(erlix_mErlixTerm,&quot;puts&quot;,erlix_term_puts,0);
   rb_define_method(erlix_mErlixTerm,&quot;==&quot;,erlix_term_eql,1);
 }</diff>
      <filename>src/erlix_term.c</filename>
    </modified>
    <modified>
      <diff>@@ -70,7 +70,7 @@ void free_erlix_term(void* p);
 
 VALUE erlix_term(ETERM *term);
 VALUE erlix_term_init_copy(VALUE copy,VALUE orig);
-VALUE erlix_term_puts(VALUE self);
+VALUE erlix_term_to_str(VALUE self);
 VALUE erlix_term_eql(VALUE left,VALUE right);
 VALUE erlix_term_match(VALUE left,VALUE string);
 VALUE erlix_term_mget(VALUE left,VALUE string,VALUE e);</diff>
      <filename>src/erlix_term.h</filename>
    </modified>
    <modified>
      <diff>@@ -27,12 +27,11 @@ VALUE erlix_tuple_init(VALUE self,VALUE ary){
     return self;
   }
   int i;
-  //check: all elements' must be ErlixTerm
-  //TODO: automatic conversions
+    //check: all elements' must be ErlixTerm or auto-convertable Type
   for(i=0;i&lt;RARRAY(array)-&gt;len;i++){
     VALUE e=RARRAY(array)-&gt;ptr[i];
     if(!IS_ETERM(e) &amp;&amp; !CAN_AUTO_CONV(e)){
-      rb_raise(rb_eTypeError,&quot;all tuple's elements must be ErlixTerm!&quot;);
+      rb_raise(rb_eTypeError,&quot;all tuple's elements must be ErlixTerm or Auto-Convertable-Type!&quot;);
     }
   }
   ETERM **tes=(ETERM**)malloc(sizeof(ETERM*)*(RARRAY(array)-&gt;len));
@@ -47,9 +46,9 @@ VALUE erlix_tuple_init(VALUE self,VALUE ary){
     }
   }
   tuple-&gt;term=erl_mk_tuple(tes,RARRAY(array)-&gt;len);
-  for(i=0;i&lt;RARRAY(array)-&gt;len;i++){
-    erl_free_term(*(tes+i));
-  }
+  //for(i=0;i&lt;RARRAY(array)-&gt;len;i++){
+  //  erl_free_term(*(tes+i));
+  //}
   free(tes);
   return self;
 }
@@ -62,7 +61,7 @@ VALUE erlix_tuple_create(int argc,VALUE *argv,VALUE klass){
   }else if(argc&gt;0){
     int i;
     //check: all elements' must be ErlixTerm
-    //TODO: automatic conversions
+    //or automatic conversions
     for(i=0;i&lt;argc;i++){
       if(!IS_ETERM(argv[i]) &amp;&amp; !CAN_AUTO_CONV(argv[i])){
         rb_raise(rb_eTypeError,&quot;all tuple's elements must be ErlixTerm!&quot;);
@@ -79,9 +78,9 @@ VALUE erlix_tuple_create(int argc,VALUE *argv,VALUE klass){
       }
     }
     rterm=erl_mk_tuple(tes,argc);
-    for(i=0;i&lt;argc;i++){
-      erl_free_term(*(tes+i));
-    }
+    //for(i=0;i&lt;argc;i++){
+    //  erl_free_term(*(tes+i));
+    //}
     free(tes);
   }
   return erlix_term(rterm);
@@ -98,12 +97,9 @@ VALUE erlix_tuple_nth(VALUE self,VALUE index){
     return Qnil;
   }
   ETERM *e=erl_element(FIX2INT(index),tuple-&gt;term);
-  return erlix_term(e);
+  return erlix_term(erl_copy_term(e));
 }
 
-//TODO
-VALUE erlix_tuple_to_str(VALUE self);
-//TODO
 VALUE erlix_tuple_to_ary(VALUE self){
   ErlixTerm *tuple;
   Data_Get_Struct(self,ErlixTerm,tuple);
@@ -112,7 +108,7 @@ VALUE erlix_tuple_to_ary(VALUE self){
   int i=0;
   for(;i&lt;len;i++){
     ETERM *e=erl_element(i+1,tuple-&gt;term);
-    rb_ary_store(ret,i,erlix_term(e));
+    rb_ary_store(ret,i,erlix_term(erl_copy_term(e)));
   }
   return ret;
 }</diff>
      <filename>src/erlix_tuple.c</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,6 @@ VALUE erlix_tuple_alloc(VALUE klass);
 VALUE erlix_tuple_init(VALUE self,VALUE ary);
 VALUE erlix_tuple_create(int argc,VALUE *argv,VALUE klass);
 VALUE erlix_tuple_nth(VALUE self,VALUE index);
-VALUE erlix_tuple_to_str(VALUE self);
 VALUE erlix_tuple_to_ary(VALUE self);
 VALUE erlix_tuple_size(VALUE self);
 VALUE erlix_tuple_etype(VALUE self);</diff>
      <filename>src/erlix_tuple.h</filename>
    </modified>
    <modified>
      <diff>@@ -29,15 +29,6 @@ VALUE erlix_uint_init(VALUE self,VALUE fix){
 }
 
 
-VALUE erlix_uint_to_str(VALUE self){
-  ErlixTerm* euint;
-  Data_Get_Struct(self,ErlixTerm,euint);
-  char buf[12];
-  memset(buf,0,12);
-  sprintf(buf,&quot;%u&quot;,ERL_INT_UVALUE(euint-&gt;term));
-  return rb_str_new2(buf);
-}
-
 VALUE erlix_uint_to_fix(VALUE self){
   ErlixTerm *euint;
   Data_Get_Struct(self,ErlixTerm,euint);
@@ -54,7 +45,6 @@ void init_erlix_uint(){
 
   rb_define_alloc_func(erlix_cErlixUInt,erlix_uint_alloc);
   rb_define_method(erlix_cErlixUInt,&quot;initialize&quot;,erlix_uint_init,1);
-  rb_define_method(erlix_cErlixUInt,&quot;to_s&quot;,erlix_uint_to_str,0);
   rb_define_method(erlix_cErlixUInt,&quot;to_i&quot;,erlix_uint_to_fix,0);
   rb_define_method(erlix_cErlixUInt,&quot;etype&quot;,erlix_uint_etype,0);
 </diff>
      <filename>src/erlix_uint.c</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,6 @@
 
 VALUE erlix_uint_alloc(VALUE klass);
 VALUE erlix_uint_init(VALUE self,VALUE fixnum);
-VALUE erlix_uint_to_str(VALUE self);
 VALUE erlix_uint_to_fix(VALUE self);
 VALUE erlix_uint_size(VALUE self);
 VALUE erlix_uint_etype(VALUE self);</diff>
      <filename>src/erlix_uint.h</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>42d7d13105411d58a5430065233dfcea3c12f577</id>
    </parent>
  </parents>
  <author>
    <name>KDr2</name>
    <email>kdr2@x-macro.com</email>
  </author>
  <url>http://github.com/KDr2/erlix/commit/b9b8b1e545f66188d15509c39b8476d680ff05a9</url>
  <id>b9b8b1e545f66188d15509c39b8476d680ff05a9</id>
  <committed-date>2009-04-30T18:34:31-07:00</committed-date>
  <authored-date>2009-04-30T18:34:31-07:00</authored-date>
  <message>add ErlixTerm.to_s,remove ErlixTerm.puts,fix some bugs about erl-term</message>
  <tree>6e07f607db904e3fedee49d1b6f1f599a8a5ae20</tree>
  <committer>
    <name>KDr2</name>
    <email>kdr2@x-macro.com</email>
  </committer>
</commit>
