<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>libc's webstation</title>
 <link href="http://libc.st/atom.xml" rel="self"/>
 <link href="http://libc.st/"/>
 <updated>2009-09-20T14:07:28+04:00</updated>
 <id>http://libc.st/</id>
 <author>
   <name>Eugene Pimenov</name>
   <email>libc@libc.st</email>
 </author>

 
 <entry>
   <title>define_method and ruby 1.8</title>
   <link href="http://libc.st/ruby/2009/09/20/define-method-and-ruby-1-8.html"/>
   <updated>2009-09-20T00:00:00+04:00</updated>
   <id>http://libc.st/ruby/2009/09/20/define-method-and-ruby-1-8</id>
   <content type="html">&lt;p&gt;The following code is not thread-safe (in Ruby 1.8):&lt;/p&gt;
&lt;p class=&quot;code ruby&quot;&gt;def quote_string(s)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;self.class.instance_eval do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;define_method(:quote_string) do |s|&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep 0.1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;quote_string(s)&lt;br /&gt;
end&lt;/p&gt;
&lt;p&gt;The reason is block argument &lt;code&gt;s&lt;/code&gt; is bound to method&amp;#8217;s argument. When new method is called all threads share the same variable, so if you call this method in several threads, it wouldn&amp;#8217;t return argument anymore.&lt;/p&gt;
&lt;p&gt;Test script is &lt;a href=&quot;/ruby/files/wierd_bug.rb&quot;&gt;here&lt;/a&gt;. When it&amp;#8217;s run, it outputs&lt;/p&gt;
&lt;p class=&quot;code shell&quot;&gt;ruby 1.8.8dev (2009-09-14) [i386-darwin10.0.0]&lt;br /&gt;
1 fail [&amp;#8220;another test&amp;#8221;, &amp;#8220;another test&amp;#8221;]&lt;br /&gt;
2 fail [&amp;#8220;another test&amp;#8221;, &amp;#8220;test&amp;#8221;]&lt;/p&gt;
&lt;p&gt;ActiveRecord has the following code&lt;/p&gt;
&lt;p class=&quot;code ruby&quot;&gt;# Quotes strings for use in &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; input in the postgres driver for better performance.&lt;br /&gt;
 def quote_string(original_value) #:nodoc:&lt;br /&gt;
 &amp;nbsp;&amp;nbsp; if @connection.respond_to?(:escape)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.class.instance_eval do&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; define_method(:quote_string) do |s|&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @connection.escape(s)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp; elsif PGconn.respond_to?(:escape)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.class.instance_eval do&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; define_method(:quote_string) do |s|&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PGconn.escape(s)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp; else&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&lt;!-- --&gt; There are some incorrectly compiled postgres drivers out there&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #&lt;!-- --&gt; that don&amp;#8217;t define PGconn.escape.&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.class.instance_eval do&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; remove_method(:quote_string)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp; end&lt;br /&gt;
 &amp;nbsp;&amp;nbsp; quote_string(original_value)&lt;br /&gt;
end&lt;/p&gt;
&lt;p&gt;So if you use ActiveRecord with postgres and ruby 1.8, make sure do not use threads ;-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>What's wrong with lambda and yield method?</title>
   <link href="http://libc.st/ruby/2009/03/03/lambda-and-call.html"/>
   <updated>2009-03-03T00:00:00+03:00</updated>
   <id>http://libc.st/ruby/2009/03/03/lambda-and-call</id>
   <content type="html">&lt;p&gt;What&amp;#8217;s wrong with lambda and yield?&lt;/p&gt;
&lt;p class=&quot;code ruby&quot;&gt;def call_block(&amp;amp;c)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;c.call&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 def yield_block(&amp;amp;c)&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;yield&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 def lambda_and_call&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;c = lambda { return 1 }&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;call_block(&amp;amp;c) + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 def lambda_and_yield&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;c = lambda { return 1 }&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;yield_block(&amp;amp;c) + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 def proc_new_and_call&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;c = Proc.new { return 1 }&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;call_block(&amp;amp;c) + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 def proc_new_and_yield&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;c = Proc.new { return 1 }&lt;br /&gt;
 &amp;nbsp;&amp;nbsp;yield_block(&amp;amp;c) + 1&lt;br /&gt;
 end&lt;br /&gt;
&lt;!-- --&gt;&lt;br /&gt;
 [:lambda_and_call, :lambda_and_yield, :proc_new_and_call, :proc_new_and_yield].each {|m| puts &amp;#8220;#{m}: #{send(m)}&amp;#8221;}&lt;/p&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;p class=&quot;code text&quot;&gt;lambda_and_call: 2&lt;br /&gt;
 lambda_and_yield: 1&lt;br /&gt;
 proc_new_and_call: 1&lt;br /&gt;
 proc_new_and_yield: 1&lt;/p&gt;
&lt;p&gt;As you can see, lambda and yield behave strangely.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hpricot on FreeBSD</title>
   <link href="http://libc.st/ruby/2009/02/26/hpricot-on-freebsd.html"/>
   <updated>2009-02-26T00:00:00+03:00</updated>
   <id>http://libc.st/ruby/2009/02/26/hpricot-on-freebsd</id>
   <content type="html">&lt;p&gt;Sometimes I wonder if FreeBSD hates me… It&amp;#8217;s that case. FreeBSD guys have done something to ruby.&lt;/p&gt;
&lt;p class=&quot;code ruby&quot;&gt;irb(main):001:0&amp;gt; require &amp;#8216;rubygems&amp;#8217;&lt;br /&gt;
  =&amp;gt; true&lt;br /&gt;
  irb(main):002:0&amp;gt; require &amp;#8216;hpricot&amp;#8217;&lt;br /&gt;
  =&amp;gt; true&lt;br /&gt;
  irb(main):003:0&amp;gt; Hpricot(&amp;#8217; &amp;lt;dd&amp;gt; &amp;lt;dl&amp;gt; &amp;lt;ul&amp;gt; &amp;lt;li&amp;gt; &amp;#8217;*200 + &amp;#8217; &amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt; &amp;lt;/dl&amp;lt; &amp;lt;/dd&amp;gt; &amp;#8217;*200)&lt;br /&gt;
  Illegal instruction: 4&lt;/p&gt;
&lt;p&gt;I can successfully run this code on Mac OS X and Linux, but it fails on every FreeBSD I tried. Technically it&amp;#8217;s not hpricot&amp;#8217;s bug. If you also have this issue you can try my &lt;a href=&quot;/ruby/files/shprot.rb&quot;&gt;hackaround for hpricot 0.6.164&lt;/a&gt;. It&amp;#8217;s a bit slower than original version, but doesn&amp;#8217;t kills ruby on FreeBSD.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; It&amp;#8217;s still doesn&amp;#8217;t work… &lt;code&gt;Hpricot&lt;/code&gt; parses ok, but &lt;code&gt;.at&lt;/code&gt; fails with the same stack overflow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; Finally, I found the solution:&lt;/p&gt;
&lt;p class=&quot;code sh&quot;&gt;curl ftp://ftp.ruby-lang.org:21//pub/ruby/1.8/ruby-1.8.6-p287.tar.bz2 -o ruby-1.8.6-p287.tar.bz2 &amp;amp;&amp;amp; \&lt;br /&gt;
 curl http://de.mirror.rubyforge.org/rubygems/rubygems-1.3.1.tgz -o rubygems-1.3.1.tgz &amp;amp;&amp;amp; \&lt;br /&gt;
 tar -jxvf ruby-1.8.6-p287.tar.bz2 &amp;amp;&amp;amp; \&lt;br /&gt;
 tar -zxvf rubygems-1.3.1.tgz &amp;amp;&amp;amp; \&lt;br /&gt;
 cd ruby-1.8.6-p287 &amp;amp;&amp;amp; \&lt;br /&gt;
 ./configure &amp;#8212;prefix=/usr/local/ruby186 &amp;#8212;with-iconv-dir=/usr/local &amp;amp;&amp;amp; \&lt;br /&gt;
 make all install &amp;amp;&amp;amp; \&lt;br /&gt;
 cd .. &amp;amp;&amp;amp; \&lt;br /&gt;
 cd rubygems-1.3.1 &amp;amp;&amp;amp; \&lt;br /&gt;
 /usr/local/ruby186/bin/ruby setup.rb &amp;amp;&amp;amp; \&lt;br /&gt;
 /usr/local/ruby186/bin/gem install hpricot&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s the second time when freebsd ports installs me software with bad patches&amp;#8230; Anybody, please consider do not installing freebsd&amp;#8230; Let it die&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Inspecting dead ruby process with gdb</title>
   <link href="http://libc.st/ruby/2009/02/23/inspecting-dead-ruby-process-with-gdb.html"/>
   <updated>2009-02-23T00:00:00+03:00</updated>
   <id>http://libc.st/ruby/2009/02/23/inspecting-dead-ruby-process-with-gdb</id>
   <content type="html">&lt;p&gt;Maybe it will be useful for someone.&lt;/p&gt;
&lt;h2&gt;What do I have?&lt;/h2&gt;
&lt;p&gt;A beautiful &lt;code&gt;ruby.core&lt;/code&gt; file from freshly died ruby process on 32-bit FreeBSD server. I personally dislike freebsd for a bunch of uncomfortable defaults, sometimes it seems for me that freebsd guys tried to make my life worse. Anyway here I am.&lt;/p&gt;
&lt;p&gt;If you have a live ruby process with fancy debug symbols, you should be reading &lt;a href=&quot;http://weblog.jamisbuck.org/2006/9/22/inspecting-a-live-ruby-process&quot;&gt;this guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;What do I do?&lt;/h2&gt;
&lt;p&gt;Okay,&lt;/p&gt;
&lt;p class=&quot;code shell&quot;&gt;gdb /usr/local/bin/ruby &amp;#8212;core ruby.code&lt;/p&gt;
&lt;p class=&quot;code gdb&quot;&gt;(gdb) bt&lt;br /&gt;
 #&lt;!-- --&gt;0  0&amp;#215;4809c38c in rb_eval () from /usr/local/lib/libruby18.so.18&lt;br /&gt;
 #&lt;!-- --&gt;1  0&amp;#215;4809dcac in rb_eval () from /usr/local/lib/libruby18.so.18&lt;br /&gt;
 #&lt;!-- --&gt;2  0&amp;#215;4809ed8a in rb_eval () from /usr/local/lib/libruby18.so.18&lt;br /&gt;
 &amp;#8230;&lt;br /&gt;
 #&lt;!-- --&gt;4731 0&amp;#215;48099a02 in ruby_exec () from /usr/local/lib/libruby18.so.18&lt;br /&gt;
 #&lt;!-- --&gt;4732 0&amp;#215;48099a3e in ruby_run () from /usr/local/lib/libruby18.so.18&lt;br /&gt;
 #&lt;!-- --&gt;4733 0&amp;#215;0804865f in main ()&lt;/p&gt;
&lt;p&gt;Woot!, 4733 stack frames. Okay let&amp;#8217;s go to ruby&amp;#8217;s source:&lt;/p&gt;
&lt;p class=&quot;code c&quot;&gt;static &lt;span class=&quot;caps&quot;&gt;VALUE&lt;/span&gt;&lt;br /&gt;
rb_eval(self, n)&lt;br /&gt;
    &lt;span class=&quot;caps&quot;&gt;VALUE&lt;/span&gt; self;&lt;br /&gt;
    &lt;span class=&quot;caps&quot;&gt;NODE&lt;/span&gt; *n;&lt;/p&gt;
&lt;p&gt;Hmm, &lt;code&gt;NODE*&lt;/code&gt; interesting.&lt;/p&gt;
&lt;p class=&quot;code c&quot;&gt;typedef struct RNode {&lt;br /&gt;
        unsigned long flags;&lt;br /&gt;
        char *nd_file;&lt;br /&gt;
&amp;#8230;&lt;br /&gt;
};&lt;/p&gt;
&lt;p class=&quot;code c&quot;&gt;#define FL_USHIFT    11&lt;br /&gt;
#define NODE_LSHIFT (FL_USHIFT+8)&lt;br /&gt;
#define nd_line(n) ((unsigned int)(((&lt;acronym title=&quot;n&quot;&gt;&lt;span class=&quot;caps&quot;&gt;RNODE&lt;/span&gt;&lt;/acronym&gt;)&amp;#8594;flags&amp;gt;&amp;gt;NODE_LSHIFT)&amp;amp;NODE_LMASK))&lt;/p&gt;
&lt;p&gt;I need the line number and the file. As you can see, that information are stored in &lt;code&gt;(RNode*)n-&amp;gt;nd_file&lt;/code&gt; and &lt;code&gt;(RNode *)n-&amp;gt;flags&amp;gt;&amp;gt;19&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, I need the second argument of &lt;code&gt;rb_eval&lt;/code&gt; function. To get it I&amp;#8217;m gonna use &lt;code&gt;info frame&lt;/code&gt;&lt;/p&gt;
&lt;p class=&quot;code gdb&quot;&gt;(gdb) info frame&lt;br /&gt;
Stack level 1, frame at 0xbfa005a0:&lt;br /&gt;
 eip = 0&amp;#215;4809dcac in rb_eval; saved eip 0&amp;#215;4809ed8a&lt;br /&gt;
 called by frame at 0xbfa00910, caller of frame at 0xbfa00230&lt;br /&gt;
 Arglist at 0xbfa00598, args: &lt;br /&gt;
 Locals at 0xbfa00598, Previous frame&amp;#8217;s sp is 0xbfa005a0&lt;br /&gt;
 Saved registers:&lt;br /&gt;
  ebx at 0xbfa0058c, ebp at 0xbfa00598, esi at 0xbfa00590, edi at 0xbfa00594, eip at 0xbfa0059c&lt;/p&gt;
&lt;p&gt;It says &lt;code&gt;Stack level 1, frame at 0xbfa005a0&lt;/code&gt; which means &lt;code&gt;0xbfa005a0&lt;/code&gt; is my first argument, and &lt;code&gt;0xbfa005a4&lt;/code&gt; is the second. All I need now: &lt;code&gt;printf &quot;%s\n&quot;, * ( * ( 0xbfa005a4 ) + 4 )&lt;/code&gt;, and:&lt;/p&gt;
&lt;p class=&quot;code gdb&quot;&gt;(gdb) printf &amp;#8220;%s\n&amp;#8221;, * ( * ( 0xbfa005a4 ) + 4)&lt;br /&gt;
/usr/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/lib/hpricot/parse.rb&lt;br /&gt;
(gdb) printf &amp;#8220;%d\n&amp;#8221;, * ( * ( 0xbfa005a4 ) ) &amp;gt;&amp;gt; 19&lt;br /&gt;
235&lt;/p&gt;
&lt;p&gt;Nice, isn&amp;#8217;t it?&lt;/p&gt;
&lt;p&gt;I defined a little macro&lt;/p&gt;
&lt;p class=&quot;code gdb&quot;&gt;define rb_current_file&lt;br /&gt;
    printf &amp;#8220;%s:%d\n&amp;#8221;, * ( * ($arg0+4) + 4), * ( * ( $arg0 + 4 ) ) &amp;gt;&amp;gt; 19&lt;br /&gt;
 end&lt;/p&gt;
&lt;p&gt;So I can &lt;code&gt;info frame frame_number_here&lt;/code&gt;, and &lt;code&gt;rb_current_file addr&lt;/code&gt; to get file and line for this stack frame. I guess there&amp;#8217;s a way to write the stack trace dumper, but I don&amp;#8217;t want to research it.&lt;/p&gt;
&lt;h2&gt;Arguments for method call&lt;/h2&gt;
&lt;p class=&quot;code gdb&quot;&gt;(gdb) info frame 4573&lt;br /&gt;
  Stack frame at 0xbfbe9790:&lt;br /&gt;
  &amp;#8230;.&lt;br /&gt;
  (gdb) rb_current_File 0xbfbe9790&lt;br /&gt;
  myscript.rb:37&lt;/p&gt;
&lt;p&gt;Where 37 line is&lt;/p&gt;
&lt;p class=&quot;code ruby&quot;&gt;hpricot = Hpricot(html) unless hpricot&lt;/p&gt;
&lt;p&gt;I set it as &lt;code&gt;frame 4573&lt;/code&gt;, and went down to &lt;code&gt;#4572 0x480a4ac6 in rb_call () from /usr/local/lib/libruby18.so.18&lt;/code&gt;. Okay it&amp;#8217;s the actual hpricot call. I need an argument of it. What should I do?. Of course, go to ruby source:&lt;/p&gt;
&lt;p class=&quot;code c&quot;&gt;rb_call(klass, recv, mid, argc, argv, scope, self)&lt;/p&gt;
&lt;p&gt;As you can see, fifth argument is what I need. I can get it by &lt;code&gt;*(frame+4*4)&lt;/code&gt;. My frame address is &lt;code&gt;0xbfbe9400&lt;/code&gt;, so I do &lt;code&gt;printf &quot;0x%x\n&quot;, *(*((unsigned long*)0xbfbe9400+4))&lt;/code&gt; and see &lt;code&gt;0xc27c304&lt;/code&gt;. It&amp;#8217;s a &lt;span class=&quot;caps&quot;&gt;VALUE&lt;/span&gt;, so it has type in the first byte: &lt;code&gt;print *0xc27c304 &amp;amp; 0x3f&lt;/code&gt; equals 7, which means it&amp;#8217;s an &lt;code&gt;RString&lt;/code&gt;.&lt;/p&gt;
&lt;p class=&quot;code c&quot;&gt;struct RString {&lt;br /&gt;
    struct RBasic basic;&lt;br /&gt;
    long len;&lt;br /&gt;
    char *ptr;&lt;br /&gt;
    &amp;#8230;&lt;br /&gt;
};&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RBasic&lt;/code&gt; is 8 bytes long. So I can get length of the string by &lt;code&gt;print *(0xc27c304+8)&lt;/code&gt;, and the string by &lt;code&gt;print (char*)*(0xc27c304+12)&lt;/code&gt;. In my case, all I need to do is &lt;code&gt;dump binary memory file.html 221081600 221301397&lt;/code&gt; and test:&lt;/p&gt;
&lt;p class=&quot;code irb&quot;&gt;$ irb&lt;br /&gt;
irb(main):001:0&amp;gt; require &amp;#8216;rubygems&amp;#8217;&lt;br /&gt;
=&amp;gt; true&lt;br /&gt;
irb(main):002:0&amp;gt; require &amp;#8216;hpricot&amp;#8217;&lt;br /&gt;
=&amp;gt; true&lt;br /&gt;
irb(main):003:0&amp;gt; Hpricot(File.read(&amp;#8216;file.html&amp;#8217;))&lt;br /&gt;
Illegal instruction: 4 (core dumped)&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it&amp;#8230; Send questions to libc at libc.st&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>tidy_ffi</title>
   <link href="http://libc.st/ruby/2009/02/22/tidy-ffi.html"/>
   <updated>2009-02-22T00:00:00+03:00</updated>
   <id>http://libc.st/ruby/2009/02/22/tidy-ffi</id>
   <content type="html">&lt;p&gt;I started &lt;a href=&quot;http://github.com/libc/tidy_ffi&quot;&gt;tidy_ffi&lt;/a&gt;. It&amp;#8217;s a Tidy bindings implemented via &lt;a href=&quot;http://kenai.com/projects/ruby-ffi&quot;&gt;&lt;span class=&quot;caps&quot;&gt;FFI&lt;/span&gt; gem&lt;/a&gt;. &lt;span class=&quot;caps&quot;&gt;FFI&lt;/span&gt; is easy and fun.&lt;/p&gt;
&lt;h2&gt;Problems of current tidy gem.&lt;/h2&gt;
&lt;p&gt;There&amp;#8217;s known bug with tidy &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;. On December 2006 tidy guys decided to change &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, they had added &lt;code&gt;allocator&lt;/code&gt; pointer in &lt;code&gt;TidyBuf&lt;/code&gt;. So there&amp;#8217;re two kinds of tidy libraries in the wild: without allocator (Mac OS X bundled one) and with allocator (newer version that can be found on linux and freebsd).&lt;/p&gt;
&lt;p&gt;The second problem it doesn&amp;#8217;t work with ruby 1.9. Ruby 1.9 came out with changed &lt;code&gt;dl&lt;/code&gt;. &lt;span class=&quot;caps&quot;&gt;FFI&lt;/span&gt; should provide ability to use tidy_ffi in rubinius and jruby as well.&lt;/p&gt;
&lt;h2&gt;Download&lt;/h2&gt;
&lt;p&gt;To install tidy_ffi type.&lt;/p&gt;
&lt;p class=&quot;code shell&quot;&gt;gem install tidy_ffi&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s it. Of course you need libffi installed, it&amp;#8217;s not a gem. Mac OS X users have it installed, others should use distro tools to install it (apt-get, rpm whatever).&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;It&amp;#8217;s quite easy too.&lt;/p&gt;
&lt;p class=&quot;code irb&quot;&gt;&amp;gt;&amp;gt; require &amp;#8216;tidy_ffi&amp;#8217;&lt;br /&gt;
=&amp;gt; true&lt;br /&gt;
&amp;gt;&amp;gt; TidyFFI::Tidy.new(&amp;#8216;test&amp;#8217;).clean&lt;br /&gt;
=&amp;gt; &amp;#8220;&amp;lt;!&lt;span class=&quot;caps&quot;&gt;DOCTYPE&lt;/span&gt; html &lt;span class=&quot;caps&quot;&gt;PUBLIC&lt;/span&gt; \&amp;#8221;-//W3C//&lt;span class=&quot;caps&quot;&gt;DTD&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; 3.2//EN\&amp;#8220;&amp;gt;\n&amp;lt;html&amp;gt;\n&amp;lt;head&amp;gt;\n&amp;lt;meta name=\&amp;#8221;generator\&amp;quot; content=\n\&amp;#8220;&lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; Tidy for Mac OS X (vers 31 October 2006 &amp;#8211; Apple Inc. build 13), see www.w3.org\&amp;#8221;&amp;gt;\n&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;\n&amp;lt;/head&amp;gt;\n&amp;lt;body&amp;gt;\ntest\n&amp;lt;/body&amp;gt;\n&amp;lt;/html&amp;gt;\n&amp;quot;&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s no way to get warnings yet. But several ways to change options for tidy.&lt;/p&gt;
&lt;p&gt;More coming soon…&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Affleck was the bomb in Phantoms</title>
   <link href="http://libc.st/life/2009/02/22/phantoms.html"/>
   <updated>2009-02-22T00:00:00+03:00</updated>
   <id>http://libc.st/life/2009/02/22/phantoms</id>
   <content type="html">&lt;p&gt;I just watched &lt;a href=&quot;http://www.imdb.com/title/tt0119891/&quot;&gt;Phantoms&lt;/a&gt;. Awesome movie… There&amp;#8217;re some lags, but anyway it&amp;#8217;s a pretty awesome movie. If you have time, go ahead and watch it.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s kinda test post :)&lt;/p&gt;</content>
 </entry>
 
 
</feed>