<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-10398581</atom:id><lastBuildDate>Thu, 19 Nov 2009 15:50:13 +0000</lastBuildDate><title>X.Y.Z</title><description>Ruby, XRuby, ANTLR, Security and else</description><link>http://seclib.blogspot.com/</link><managingEditor>noreply@blogger.com (xue.yong.zhi)</managingEditor><generator>Blogger</generator><openSearch:totalResults>70</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-4090013000828096332</guid><pubDate>Mon, 12 Jan 2009 21:31:00 +0000</pubDate><atom:updated>2009-01-12T13:54:18.656-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>cron test debug</category><title>How to debug or test cron script</title><description>If your simple cron script (/etc/cron.daily, etc/cron.hourly etc) does not run as expected, do the following:&lt;br /&gt;&lt;br /&gt;1. be sure to have '#!/bin/sh' as the first line&lt;br /&gt;2. make sure the script's name does not contains '.'. for example, you should rename 'yourscript.sh' to 'yourscript'.&lt;br /&gt;3. use absolute path if you need to read/write files in the script&lt;br /&gt;4. try run the script in the shell to make sure there is no obvious problem&lt;br /&gt;5. 'run-parts --test /etc/cron.hourly/' will tell you what scripts will run, you should see your script in the list&lt;br /&gt;6. next try to run it like cron does, for example:&lt;br /&gt;cd / &amp;&amp; run-parts --report /etc/cron.hourly&lt;br /&gt;7. cron uses syslog for logging. Check your syslog config file ( /etc/syslog.conf) to see where the log is, and check the log for errors.&lt;br /&gt;&lt;br /&gt;Ref:&lt;br /&gt;[1] Why are cron.hourly files not running? SOLVED&lt;br /&gt;&lt;a href="https://lists.ubuntu.com/archives/ubuntu-users/2007-July/118973.html"&gt;https://lists.ubuntu.com/archives/ubuntu-users/2007-July/118973.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-4090013000828096332?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2009/01/how-to-debug-or-test-cron-script.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-325777667672184618</guid><pubDate>Tue, 25 Mar 2008 01:40:00 +0000</pubDate><atom:updated>2008-03-24T18:41:27.047-07:00</atom:updated><title>Google Summer of Code with Ruby Central</title><description>Ruby Central will once again participate the Google Summer of Code in 2008 as a mentoring organization:&lt;br /&gt;&lt;a href="http://code.google.com/soc/2008/ruby/about.html"&gt;http://code.google.com/soc/2008/ruby/about.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://on-ruby.blogspot.com"&gt;Pat Eyler&lt;/a&gt; has put together an &lt;a href="http://rubycentral.com/projects/gsoc-2008/ideas-for-gsoc-2008"&gt; idea page&lt;/a&gt;, which is a great reference. While every organization may have different policy, Ruby Central has been happy to see students' own ideas in the past, and I believe this year is not an exception. Feel free to submit your own exciting ideas so that the mentors can pick the best ones.&lt;br /&gt;&lt;br /&gt;Today is the first day for Google to accept student applications. For student who are interested in participating, my advise is to apply as early as possible: normally students who apply early has a slight advantage because mentors will have more time to read their applications. &lt;br /&gt;&lt;br /&gt;And another advise for future GSOC students is: once accepted, please make sure you are well prepared for the program. Google and mentors normally assume you to work near fulltime in the summer, but unfortunately every year we saw 'disappearing' students during the program. If for some reasons you can not make it after being accepted, please communicate with your mentor organization early so that they can make better adjustment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-325777667672184618?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2008/03/google-summer-of-code-with-ruby-central.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-7819666222444989529</guid><pubDate>Tue, 25 Mar 2008 00:57:00 +0000</pubDate><atom:updated>2008-03-24T17:57:52.161-07:00</atom:updated><title>XRuby license changed to BSD</title><description>XRuby had been licensed under GNU General Public License v2. For people who want to create solutions based on XRuby, this means they had to adopt GPL as well, which is not always possible. So since &lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;0.3.3&lt;/a&gt;, we changed the license to BSD. Hopefully this will help XRuby gain more acceptance, especially from the corporate world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-7819666222444989529?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2008/03/xruby-license-changed-to-bsd.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-5608027927927871346</guid><pubDate>Mon, 24 Sep 2007 14:45:00 +0000</pubDate><atom:updated>2007-09-24T07:45:52.155-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>XRuby 0.3.1 released</title><description>XRuby 0.3.1 is released today and you can download the latest version here:&lt;br /&gt;&lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The major changes in this version are:&lt;br /&gt;&lt;br /&gt;1. &lt;span style="font-weight: bold;"&gt;Ruby standard libraries are now pre-compiled&lt;/span&gt; and the compilation results (java bytecode) are shipped as part of the xruby.jar. This makes deployment really easy, as there is one jar file to deal with. Pre-compiled libraries means it isn't necessary to compile these code every time by the user which is helpful to performance.&lt;br /&gt;&lt;br /&gt;The size of the final jar may cause some concerns: while the number of ruby stdlib supported by the current version of XRuby is still limited, the size of the compiled stdlib has already reached 2,000 KB (the entire xruby-0.3.1.jar is over 4,000 KB). Maybe we will ship ruby stdlib in a separated jar files in the future.&lt;br /&gt;&lt;br /&gt;2. Use annotation and code generation to bind Java level method to Ruby level method. We started to make this change in 0.3.0 and finished it in 0.3.1. It helped us to get rid of lots of redundant code. For more information about this change, please read our &lt;a href="http://xruby.blogspot.com/2007/08/xruby-030-released.html"&gt;last announcement&lt;/a&gt; and dreamhead's articles(&lt;a href="http://dreamhead.blogbus.com/logs/7226338.html"&gt;1&lt;/a&gt;, &lt;a href="http://dreamhead.blogbus.com/logs/7502504.html"&gt;2&lt;/a&gt;) on his blogs (in Chinese).&lt;br /&gt;&lt;br /&gt;Thank everyone who has contributed to this release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-5608027927927871346?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/09/xruby-031-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-3256385091342192863</guid><pubDate>Wed, 08 Aug 2007 05:05:00 +0000</pubDate><atom:updated>2007-08-07T22:06:16.796-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>xruby 0.3.0 released</title><description>I am pleased to announce that XRuby 0.3.0 is released:&lt;br /&gt;&lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We have fixed lots of bugs and made significant improvement in the code.&lt;br /&gt;&lt;br /&gt;Changes from 0.2.1 to 0.3.0:&lt;br /&gt;1. Use annotation and code generation to bind Java level method to Ruby level method (I will talk more about this later).&lt;br /&gt;&lt;br /&gt;2. More unit tests passed. We have not eliminated all test failures in test/ruby. But as most of the failures are caused by the implementation of builtin libraries, we will be able to fixed them soon in 0.4.0.&lt;br /&gt;&lt;br /&gt;Changes from 0.2.0 to 0.2.1:&lt;br /&gt;1) Dreamhead optimized method/block calls for methods with zero/one&lt;br /&gt;arguments. It makes our performance even better.&lt;br /&gt;&lt;br /&gt;2) ZhangYu improved Java integration significantly, he also created a wiki page with lots of good examples:&lt;br /&gt;&lt;a href="http://code.google.com/p/xruby/wiki/JavaIntegration"&gt;http://code.google.com/p/xruby/wiki/JavaIntegration &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3) Mechiland and I made more ruby unit tests pass.&lt;br /&gt;&lt;br /&gt;The most significant change of 0.3.0 is the using of annotation and code generation to bind Java level method to ruby level method. The idea was inspired by the discussions about Java 5 on &lt;a href="http://archive.jruby.codehaus.org/dev"&gt;jruby's maillist&lt;/a&gt;, and dreamhead turned it into reality quickly.&lt;br /&gt;&lt;br /&gt;As we know, a Ruby method does a little bit more than a Java method. So if we have a method like this in Java:&lt;br /&gt;&lt;pre&gt;public class RubyString {&lt;br /&gt;   public RubyFloat to_f() {&lt;br /&gt;       ...&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;To turn it (RubyString.to_f) into a Ruby level method, we have to add a few more code to 'wrap' into a class (extends RubyMethod) and 'register' it (defineMethod), e.g:&lt;br /&gt;&lt;pre&gt;public class String_to_f extends RubyNoArgMethod {&lt;br /&gt;   protected RubyValue run(RubyValue receiver, RubyBlock block) {&lt;br /&gt;       return ((RubyString)receiver).to_f();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;RubyRuntime.StringClass.defineMethod("to_f", new String_to_f());&lt;br /&gt;&lt;/pre&gt;For every method, we need to write similar code and it is not fun to repeat yourself. In 0.3.0, we no longer have to do this anymore. As as long as you add annotation like this:&lt;br /&gt;&lt;pre&gt;@RubyLevelClass(name="String")&lt;br /&gt;public class RubyString {&lt;br /&gt;   @RubyLevelMethod(name="to_f")&lt;br /&gt;   public RubyFloat to_f() {&lt;br /&gt;       ...&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;XRuby will turn it into a Ruby level method automatically (using ASM to generate Java bytecode).&lt;br /&gt;&lt;br /&gt;I have not used Java 5's annotation feature before, but this looks like an very elegant solution.&lt;br /&gt;&lt;br /&gt;Thank everyone who has contributed to this release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-3256385091342192863?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/08/xruby-030-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-2842362357185648651</guid><pubDate>Tue, 12 Jun 2007 15:15:00 +0000</pubDate><atom:updated>2007-06-12T08:15:11.232-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>ruby -y</title><description>For people who are interested in how ruby's yacc parser works, there is an undocumented command line option("-y") that may be helpful. It will display a trace of the parser's operations. &lt;br /&gt;&lt;br /&gt;To use it, you need to clear your RUBYOPT environment variable to NOT use "rubygems" (this will break some ruby applications), otherwise it will make too much noise.&lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ruby -y -e "a=1"&lt;br /&gt;Starting parse&lt;br /&gt;Entering state 0&lt;br /&gt;Reducing stack by rule 1 (line 328), -&gt; @1&lt;br /&gt;Stack now 0&lt;br /&gt;Entering state 2&lt;br /&gt;Reading a token: Next token is token tIDENTIFIER ()&lt;br /&gt;Shifting token tIDENTIFIER, Entering state 34&lt;br /&gt;Reading a token: Next token is token '=' ()&lt;br /&gt;Reducing stack by rule 418 (line 2146), tIDENTIFIER -&gt; variable&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 90&lt;br /&gt;Next token is token '=' ()&lt;br /&gt;Reducing stack by rule 83 (line 827), variable -&gt; lhs&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 73&lt;br /&gt;Next token is token '=' ()&lt;br /&gt;Shifting token '=', Entering state 315&lt;br /&gt;Reading a token: Next token is token tINTEGER ()&lt;br /&gt;Shifting token tINTEGER, Entering state 40&lt;br /&gt;Reducing stack by rule 414 (line 2134), tINTEGER -&gt; numeric&lt;br /&gt;Stack now 0 2 73 315&lt;br /&gt;Entering state 89&lt;br /&gt;Reducing stack by rule 376 (line 1899), numeric -&gt; literal&lt;br /&gt;Stack now 0 2 73 315&lt;br /&gt;Entering state 79&lt;br /&gt;Reducing stack by rule 267 (line 1421), literal -&gt; primary&lt;br /&gt;Stack now 0 2 73 315&lt;br /&gt;Entering state 75&lt;br /&gt;Reading a token: Next token is token '\n' ()&lt;br /&gt;Reducing stack by rule 217 (line 1199), primary -&gt; arg&lt;br /&gt;Stack now 0 2 73 315&lt;br /&gt;Entering state 488&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Reducing stack by rule 173 (line 953), lhs '=' arg -&gt; arg&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 74&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Reducing stack by rule 40 (line 616), arg -&gt; expr&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 64&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Reducing stack by rule 34 (line 596), expr -&gt; stmt&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 63&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Reducing stack by rule 6 (line 381), stmt -&gt; stmts&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 62&lt;br /&gt;Next token is token '\n' ()&lt;br /&gt;Shifting token '\n', Entering state 216&lt;br /&gt;Reducing stack by rule 496 (line 2429), '\n' -&gt; term&lt;br /&gt;Stack now 0 2 62&lt;br /&gt;Entering state 220&lt;br /&gt;Reducing stack by rule 497 (line 2432), term -&gt; terms&lt;br /&gt;Stack now 0 2 62&lt;br /&gt;Entering state 300&lt;br /&gt;Reading a token: Now at end of input.&lt;br /&gt;Reducing stack by rule 489 (line 2416), terms -&gt; opt_terms&lt;br /&gt;Stack now 0 2 62&lt;br /&gt;Entering state 299&lt;br /&gt;Reducing stack by rule 4 (line 373), stmts opt_terms -&gt; compstmt&lt;br /&gt;Stack now 0 2&lt;br /&gt;Entering state 61&lt;br /&gt;Reducing stack by rule 2 (line 328), @1 compstmt -&gt; program&lt;br /&gt;Stack now 0&lt;br /&gt;Entering state 1&lt;br /&gt;Now at end of input.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;XRuby's ANTLR parser does not have this option. But as ANRLE produces human readable code, you can just read the generated code or step through it in a debugger to learn how it works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-2842362357185648651?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/06/ruby-y.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-7695307076536751076</guid><pubDate>Tue, 15 May 2007 15:18:00 +0000</pubDate><atom:updated>2007-05-15T08:19:20.679-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>XRuby 0.2.0 released</title><description>I am glad to announce that XRuby 0.2.0 is now available for download at: &lt;br /&gt;&lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a summary of major changes in this release:&lt;br /&gt;&lt;br /&gt;1. Beanworms started to work on the debugging support and we now have a basic debugger in trunk.&lt;br /&gt;2. Zhang Yu and Haofei Wang added/fixed lots of builtin methods&lt;br /&gt;3. Dreamhead rewrote RubySymbol as the old one was plain wrong&lt;br /&gt;4. As test::unit works on XRuby, we imported unit tests from c ruby (test\ruby) to test our implementation. The result was not very impressive so far, less than half of the tests passed. We are planning to make all tests pass in the coming weeks.&lt;br /&gt;5. Meanwhile, Femto is leading our efforts to create an ANTLR v3 based ruby parser in another branch. Upgrading our parser from ANTLR v2 to v3 is indeed challenging, but he has make very impressive progress.&lt;br /&gt;&lt;br /&gt;Thank you everybody who contributed to this release!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-7695307076536751076?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/05/xruby-020-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-3092927218827532150</guid><pubDate>Tue, 17 Apr 2007 11:16:00 +0000</pubDate><atom:updated>2007-04-27T04:27:53.454-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>InfoQ article on XRuby</title><description>Werner Schuster from InfoQ has a very nice article about XRuby, you can &lt;a href="http://www.infoq.com/news/2007/04/xruby-another-ruby-on-jvm"&gt;read it here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;UPDATE 04/27/2007: InfoQ China had an interview with our core developer Dreamhead. You can read it &lt;a href="http://www.infoq.com/cn/news/2007/04/interview-xruby-developer"&gt;here (in Chinese)&lt;/a&gt;. And congratulations to Dreamhead for joining Thoughtworks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-3092927218827532150?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/04/infoq-article-on-xruby.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-5479505336169999604</guid><pubDate>Tue, 10 Apr 2007 16:15:00 +0000</pubDate><atom:updated>2007-04-10T17:31:34.857-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>xruby</category><title>XRuby 0.1.4 released</title><description>I am glad to announce that XRuby 0.1.4 is now available for download at: &lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The most significant change in this release is: one of our team member, dreamhead, single-handly created a new runtime (the core of the system that manages ruby types, methods...) to make it very close to the classic C ruby, and therefore fixed several compatibility issues with C ruby. As a translator of the Chinese version Ruby Hacking Guide, dreamhead has very good knowledge of the ruby internal and gives a great lift on the XRuby's development.&lt;br /&gt;&lt;br /&gt;As we have learned rewriting is very difficult, we learned it again in a hard way. Dreamhead wrote most of code last year, several months before 0.1.0 release. First we tried to make a wholesale replacement of the runtime, but problems were here and there and lots of unit tests broke. Since we do not want to have a broken system in the SVN trunk, we decided to take 'refactoring' approach and merge changes step by step. It is still very hard, but dreamhead made lots of efforts and finished the merge yesterday.&lt;br /&gt;&lt;br /&gt;Actually it may take less time if we insist on following the 'rewrite' approach (replace all the old code and fix broken tests), but the benefit of 'refactoring' is significant: it gives us a stable code base so that we made several releases during this big change.&lt;br /&gt;&lt;br /&gt;There are more exciting news behind the scene now: Beanworms is working on the debugger support, and Femto and Yuesefa have showed interest to migrate our ruby parser to ANTLR 3.0.&lt;br /&gt;&lt;br /&gt;Thank you for people who helps us on making this release. It has been a great learning experience working with the project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-5479505336169999604?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/04/xruby-014-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-5349122123675144026</guid><pubDate>Mon, 12 Mar 2007 03:15:00 +0000</pubDate><atom:updated>2007-03-11T20:16:18.211-07:00</atom:updated><title>Ruby builtin in pure Ruby</title><description>One of the best things I love about rubinius project is: their developers try to keep the dependency on system language (C in their case) minimal, and they take it seriously. Take a look of &lt;a href="http://code.fallingsnow.net/svn/rubinius/trunk/kernel/core/"&gt;http://code.fallingsnow.net/svn/rubinius/trunk/kernel/core/&lt;/a&gt;, you will find out lots of buitlin libraries are implemented in pure ruby, even lots of string functions.&lt;br /&gt;&lt;br /&gt;Pure ruby builtin has some drawbacks, though. One is performance penalty, the other is potential side effects. For example, basically &lt;b&gt;Integer#times&lt;/b&gt; can be implemented as simple as this in pure ruby:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Integer&lt;br /&gt; def times  &lt;br /&gt;  i = 0  &lt;br /&gt;  while i &lt; self&lt;br /&gt;   yield i&lt;br /&gt;   i += 1;  &lt;br /&gt;  end &lt;br /&gt;  self&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But this version of Integer#times does not work exactly the same as Ruby 1.8.5. If an user want to override Fixnum#+ (this may never happen in real life):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Fixnum&lt;br /&gt;  def + x&lt;br /&gt;    return 9999&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Our Integer#times's behavior will change, while Ruby 1.8.5 won't. That is because Ruby 1.8.5's implementation (int_dotimes() in Numeric.c) optimizes for Fixnum: it does not  call '+' method dynamically for Fixnum, instead, it just increases the integer directly.  If you want to implement this method as same as Ruby 1.8.5 then you have to write code in system language.&lt;br /&gt;&lt;br /&gt;This kind of optimization is all over the place in c ruby. I am not clear about its motivation, but I guess performance is one of the reasons. For example, "&lt;b&gt;30000000.times {|x|}&lt;/b&gt;" is about twice faster than "&lt;b&gt;i = 0; while i &lt; 30000000; i +=1; end&lt;/b&gt;" in Ruby 1.8.5.&lt;br /&gt;&lt;br /&gt;Difference people may have different opinions on what the 'right' behavior should be. As for me, I like the behavior of the pure ruby implementation better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-5349122123675144026?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/03/ruby-builtin-in-pure-ruby.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-5966502233960701190</guid><pubDate>Wed, 07 Mar 2007 03:18:00 +0000</pubDate><atom:updated>2007-03-07T06:34:52.776-08:00</atom:updated><title>XRuby is faster than Ruby 1.8.5 in most benchmarks</title><description>Two weeks ago, Antonio Cangiano compared the &lt;a href="http://www.antoniocangiano.com/articles/2007/02/19/ruby-implementations-shootout-ruby-vs-yarv-vs-jruby-vs-gardens-point-ruby-net-vs-rubinius-vs-cardinal"&gt;performance of different ruby implementations&lt;/a&gt; using Ruby 1.9 (YARV)'s benchmark suite. His numbers got me thinking: all alternative implementations performed badly -- most are even way slower than ruby 1.8.5. Does it signal that JVM and .NET are bad platform for Ruby language? &lt;br /&gt;&lt;br /&gt;With this doubt I tried the benchmark with XRuby. XRuby is a ruby compiler. Unlike other implementations, it generates Java bytecode that run directly on JVM. But at first the numbers are not impressive: the 0.1.2 version is still slower than Ruby 1.8.5 in most of the cases.&lt;br /&gt;&lt;br /&gt;Maybe I should mention that the XRuby team had done virtually nothing for performance before, and we would avoid optimization as long as possible if it makes our code complicated. But after doing some measurements, it turns out our bad performance are largely caused by a logic 'error': as we know Ruby Fixnum can not have singleton methods, but in 0.1.2 it still lookup an empty method table. And along with some bad code practices (iterating an empty ArrayList without checking if it is empty first etc), it makes method lookup much slower than it should be. &lt;br /&gt;&lt;br /&gt;I fixed the problem by adding about 10 lines of code, and got great result: &lt;b&gt;In most benchmarks, XRuby 0.1.3 is faster than Ruby 1.8.5. For some, faster in a significant way&lt;/b&gt;. There are still some tests in which we are slower, but it looks like caused by poorly implemented builtin.&lt;br /&gt;&lt;br /&gt;The following table shows the benchmark result for XRuby 0.1.3. The best part is: &lt;b&gt;we did it without a method cache&lt;/b&gt;. YARV is still faster than XRuby, but we have lots of room to improve too.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&gt;java -Xmx512m -jar xruby-0.1.3.jar benchmark\run.rb&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Test&lt;/td&gt;&lt;td&gt;Ruby 1.8.5&lt;/td&gt;&lt;td&gt;XRuby 0.1.3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_answer.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_factorial.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_fib.rb&lt;/td&gt;&lt;td&gt;20.02&lt;/td&gt;&lt;td BGCOLOR=green&gt;12.29&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_mandelbrot.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;7.099&lt;/td&gt;&lt;td&gt;8.252&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_pentomino.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;289.8&lt;/td&gt;&lt;td&gt;538.5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_raise.rb&lt;/td&gt;&lt;td&gt;4.846&lt;/td&gt;&lt;td BGCOLOR=green&gt;3.986&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_strconcat.rb&lt;/td&gt;&lt;td&gt;5.898&lt;/td&gt;&lt;td BGCOLOR=green&gt;3.234&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_tak.rb&lt;/td&gt;&lt;td&gt;26.14&lt;/td&gt;&lt;td BGCOLOR=green&gt;22.12&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_tarai.rb&lt;/td&gt;&lt;td&gt;20.89&lt;/td&gt;&lt;td BGCOLOR=green&gt;18.35&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_times.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;14.28&lt;/td&gt;&lt;td&gt;19.30&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_whileloop.rb&lt;/td&gt;&lt;td&gt;26.03&lt;/td&gt;&lt;td BGCOLOR=green&gt;19.27&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_whileloop2.rb&lt;/td&gt;&lt;td&gt;5.257&lt;/td&gt;&lt;td BGCOLOR=green&gt;4.786&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_ackermann.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_array.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;19.17&lt;/td&gt;&lt;td&gt;46.84&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_concatenate.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;5.727&lt;/td&gt;&lt;td&gt;9.684&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_count_words.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;2.944&lt;/td&gt;&lt;td&gt;45.50&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_exception.rb&lt;/td&gt;&lt;td&gt;9.793&lt;/td&gt;&lt;td BGCOLOR=green&gt;7.399&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_lists.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;3.666&lt;/td&gt;&lt;td&gt;24.59&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_matrix.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;6.249&lt;/td&gt;&lt;td&gt;8.452&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_nested_loop.rb&lt;/td&gt;&lt;td&gt;15.17&lt;/td&gt;&lt;td BGCOLOR=green&gt;13.45&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_object.rb&lt;/td&gt;&lt;td&gt;21.49&lt;/td&gt;&lt;td BGCOLOR=green&gt;7.991&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_random.rb&lt;/td&gt;&lt;td&gt;6.169&lt;/td&gt;&lt;td BGCOLOR=green&gt;5.888&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_sieve.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;2.042&lt;/td&gt;&lt;td&gt;2.753&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_block.rb&lt;/td&gt;&lt;td&gt;64.57&lt;/td&gt;&lt;td BGCOLOR=green&gt;38.69&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_const.rb&lt;/td&gt;&lt;td&gt;47.47&lt;/td&gt;&lt;td BGCOLOR=green&gt;25.57&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_ensure.rb&lt;/td&gt;&lt;td&gt;45.54&lt;/td&gt;&lt;td BGCOLOR=green&gt;20.01&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_length.rb&lt;/td&gt;&lt;td&gt;55.50&lt;/td&gt;&lt;td BGCOLOR=green&gt;40.89&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_rescue.rb&lt;/td&gt;&lt;td&gt;39.61&lt;/td&gt;&lt;td BGCOLOR=green&gt;20.64&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_simplereturn.rb&lt;/td&gt;&lt;td&gt;56.02&lt;/td&gt;&lt;td BGCOLOR=green&gt;29.06&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_swap.rb&lt;/td&gt;&lt;td&gt;76.35&lt;/td&gt;&lt;td BGCOLOR=green&gt;30.52&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_array.rb&lt;/td&gt;&lt;td&gt;19.34&lt;/td&gt;&lt;td BGCOLOR=green&gt;8.532&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_method.rb&lt;/td&gt;&lt;td&gt;33.72&lt;/td&gt;&lt;td BGCOLOR=green&gt;19.63&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_poly_method.rb&lt;/td&gt;&lt;td&gt;45.23&lt;/td&gt;&lt;td BGCOLOR=green&gt;20.62&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_poly_method_ov.rb&lt;/td&gt;&lt;td&gt;12.64&lt;/td&gt;&lt;td BGCOLOR=green&gt;8.261&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_proc.rb&lt;/td&gt;&lt;td&gt;21.08&lt;/td&gt;&lt;td BGCOLOR=green&gt;17.86&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_regexp.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;13.09&lt;/td&gt;&lt;td&gt;30.87&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_send.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;11.71&lt;/td&gt;&lt;td&gt;15.75&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_super.rb&lt;/td&gt;&lt;td&gt;13.92&lt;/td&gt;&lt;td BGCOLOR=green&gt;7.510&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_unif1.rb&lt;/td&gt;&lt;td&gt;11.30&lt;/td&gt;&lt;td BGCOLOR=green&gt;8.292&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_zsuper.rb&lt;/td&gt;&lt;td&gt;15.71&lt;/td&gt;&lt;td BGCOLOR=green&gt;7.740&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm3_thread_create_join.rb&lt;/td&gt;&lt;td BGCOLOR=green&gt;0.110&lt;/td&gt;&lt;td&gt;1.331&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;* The test environment is Intel Pentium M 1G CPU, 1G Memory, Windows XP SP2, Java 1.5.0_09.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-5966502233960701190?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/03/xruby-runs-most-benchmark-faster-than.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-4321104369681836049</guid><pubDate>Thu, 01 Mar 2007 03:13:00 +0000</pubDate><atom:updated>2007-03-01T21:59:43.043-08:00</atom:updated><title>XRuby 0.1.2 released</title><description>XRuby 0.1.2 is now available for download from the project download page: &lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This latest release contains more built-in libraries and a few bug fixes for the compiler. We expect to release a new stable version every month.&lt;br /&gt;&lt;br /&gt;Last week, Antonio Cangiano did a very interesting job to&lt;a href="http://www.antoniocangiano.com/articles/2007/02/19/ruby-implementations-shootout-ruby-vs-yarv-vs-jruby-vs-gardens-point-ruby-net-vs-rubinius-vs-cardinal"&gt; compare the performance of different ruby implementations&lt;/a&gt; using YARV's benchmark suite. XRuby is not included in his test as Antonio may not know our project exists. For people who are interested, here is the XRuby's performance data (due to my limited resource, only ruby 1.8.5 interpreter was compared):&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&gt;java -Xmx512m -jar xruby-0.1.2.jar benchmark\run.rb&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Test&lt;/td&gt;&lt;td&gt;Ruby 1.8.5&lt;/td&gt;&lt;td&gt;XRuby 0.1.2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_answer.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_factorial.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_fib.rb&lt;/td&gt;&lt;td&gt;20.42&lt;/td&gt;&lt;td&gt;33.84&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_mandelbrot.rb&lt;/td&gt;&lt;td&gt;7.270&lt;/td&gt;&lt;td&gt;15.33&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_pentomino.rb&lt;/td&gt;&lt;td&gt;294.2&lt;/td&gt;&lt;td&gt;956.9&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_raise.rb&lt;/td&gt;&lt;td&gt;4.906&lt;/td&gt;&lt;td&gt;4.597&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_strconcat.rb&lt;/td&gt;&lt;td&gt;5.917&lt;/td&gt;&lt;td&gt;5.858&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_tak.rb&lt;/td&gt;&lt;td&gt;26.46&lt;/td&gt;&lt;td&gt;38.95&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_app_tarai.rb&lt;/td&gt;&lt;td&gt;21.08&lt;/td&gt;&lt;td&gt;35.51&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_times.rb&lt;/td&gt;&lt;td&gt;14.83&lt;/td&gt;&lt;td&gt;93.55&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_whileloop.rb&lt;/td&gt;&lt;td&gt;26.26&lt;/td&gt;&lt;td&gt;76.5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_loop_whileloop2.rb&lt;/td&gt;&lt;td&gt;5.327&lt;/td&gt;&lt;td&gt;16.15&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_ackermann.rb&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;td&gt;fail&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_array.rb&lt;/td&gt;&lt;td&gt;19.35&lt;/td&gt;&lt;td&gt;300.2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_concatenate.rb&lt;/td&gt;&lt;td&gt;5.868&lt;/td&gt;&lt;td&gt;26.58&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_count_words.rb&lt;/td&gt;&lt;td&gt;2.253&lt;/td&gt;&lt;td&gt;46.43&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_exception.rb&lt;/td&gt;&lt;td&gt;9.893&lt;/td&gt;&lt;td&gt;9.973&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_lists.rb&lt;/td&gt;&lt;td&gt;3.696&lt;/td&gt;&lt;td&gt;41.04&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_matrix.rb&lt;/td&gt;&lt;td&gt;6.328&lt;/td&gt;&lt;td&gt;21.29&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_nested_loop.rb&lt;/td&gt;&lt;td&gt;15.38&lt;/td&gt;&lt;td&gt;68.20&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_object.rb&lt;/td&gt;&lt;td&gt;21.97&lt;/td&gt;&lt;td&gt;20.77&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_random.rb&lt;/td&gt;&lt;td&gt;6.269&lt;/td&gt;&lt;td&gt;15.69&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_so_sieve.rb&lt;/td&gt;&lt;td&gt;1.992&lt;/td&gt;&lt;td&gt;5.476&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_block.rb&lt;/td&gt;&lt;td&gt;65.67&lt;/td&gt;&lt;td&gt;98.91&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_const.rb&lt;/td&gt;&lt;td&gt;48.05&lt;/td&gt;&lt;td&gt;82.31&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_ensure.rb&lt;/td&gt;&lt;td&gt;46.19&lt;/td&gt;&lt;td&gt;75.38&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_length.rb&lt;/td&gt;&lt;td&gt;55.62&lt;/td&gt;&lt;td&gt;105.6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_rescue.rb&lt;/td&gt;&lt;td&gt;36.47&lt;/td&gt;&lt;td&gt;80.91&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_simplereturn.rb&lt;/td&gt;&lt;td&gt;57.12&lt;/td&gt;&lt;td&gt;88.16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm1_swap.rb&lt;/td&gt;&lt;td&gt;76.21&lt;/td&gt;&lt;td&gt;85.73&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_array.rb&lt;/td&gt;&lt;td&gt;18.64&lt;/td&gt;&lt;td&gt;19.65&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_method.rb&lt;/td&gt;&lt;td&gt;33.41&lt;/td&gt;&lt;td&gt;35.32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_poly_method.rb&lt;/td&gt;&lt;td&gt;45.42&lt;/td&gt;&lt;td&gt;47.78&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_poly_method_ov.rb&lt;/td&gt;&lt;td&gt;12.81&lt;/td&gt;&lt;td&gt;25.98&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_proc.rb&lt;/td&gt;&lt;td&gt;21.54&lt;/td&gt;&lt;td&gt;31.23&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_regexp.rb&lt;/td&gt;&lt;td&gt;13.40&lt;/td&gt;&lt;td&gt;52.35&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_send.rb&lt;/td&gt;&lt;td&gt;11.87&lt;/td&gt;&lt;td&gt;31.60&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_super.rb&lt;/td&gt;&lt;td&gt;13.98&lt;/td&gt;&lt;td&gt;20.25&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_unif1.rb&lt;/td&gt;&lt;td&gt;11.46&lt;/td&gt;&lt;td&gt;19.95&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm2_zsuper.rb&lt;/td&gt;&lt;td&gt;15.84&lt;/td&gt;&lt;td&gt;21.92&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bm_vm3_thread_create_join.rb&lt;/td&gt;&lt;td&gt;0.120&lt;/td&gt;&lt;td&gt;1.402&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The test environment is Intel Pentium M 1G CPU, 1G Memory, Windows XP SP2, Java 1.5.0_09. It may be worth to mention we have done almost nothing for optimization, not even a simple method cache. I think it is quite possible for a JVM based ruby compiler to beat the classic Ruby interpreter on performance, while YARV's number is going to be very hard for us to reach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-4321104369681836049?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/02/xruby-012-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-6900737948665511027</guid><pubDate>Mon, 19 Feb 2007 03:33:00 +0000</pubDate><atom:updated>2007-02-18T19:33:58.753-08:00</atom:updated><title>On-Ruby interview</title><description>Pat Eyler recently interviewed XRuby team, the first episode is  now posted on his popular On-Ruby blog: &lt;a href="http://on-ruby.blogspot.com/2007/02/serial-xruby-interview-episode-i.html"&gt;http://on-ruby.blogspot.com/2007/02/serial-xruby-interview-episode-i.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-6900737948665511027?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/02/on-ruby-interview.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-312769520467144627</guid><pubDate>Mon, 29 Jan 2007 22:16:00 +0000</pubDate><atom:updated>2007-01-29T14:18:23.215-08:00</atom:updated><title>XRuby 0.1.0 released</title><description>[Link of this article: &lt;a href="http://xruby.blogspot.com/2007/01/xruby-010-released.html"&gt;http://xruby.blogspot.com/2007/01/xruby-010-released.html&lt;/a&gt;]&lt;br/&gt;&lt;br/&gt;Today I am glad to announce the release XRuby 0.1.0 , a ruby compiler which compiles ruby script (.rb) to java bytecode (.class).  You can download it from here: &lt;a href="http://code.google.com/p/xruby/downloads/list"&gt;http://code.google.com/p/xruby/downloads/list&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;XRuby 0.1.0 is the first release of XRuby. It is able to pass all tests in samples/test.rb - a decent test suite that comes with ruby installation.&lt;br/&gt;&lt;br/&gt;As a compiler, XRuby compiles ruby source code so that your program can run on top of Java Virtual Machine.  For example, if you have a ruby script like this:&lt;br/&gt;&lt;br/&gt;&lt;i&gt;class MyClass&lt;br/&gt;   def say_hello_three_times&lt;br/&gt;      3.times {puts "hello"}&lt;br/&gt;   end&lt;br/&gt;end&lt;br/&gt;&lt;br/&gt;MyClass.new.say_hello_three_times&lt;/i&gt;&lt;br/&gt;&lt;br/&gt;You can compile it with XRuby (assuming its name is test.rb):&lt;br/&gt;&lt;br/&gt;&lt;i&gt;&gt;java -jar xruby-0.1.0.jar -c test.rb&lt;/i&gt;&lt;br/&gt;&lt;br/&gt;The compiler will generate a test.jar. It can be launched as a regular java application, with the following command: &lt;br/&gt;&lt;br/&gt;&lt;i&gt;&gt;java -jar test.jar&lt;br/&gt;hello&lt;br/&gt;hello&lt;br/&gt;hello&lt;/i&gt;&lt;br/&gt;&lt;br/&gt;For your convenience, you can also run the script directly (without -c option), just like the classic ruby interpreter. Under the hood it compiles the script then run the bytecode:&lt;br/&gt;&lt;br/&gt;&lt;i&gt;&gt;java -jar xruby-0.1.0.jar test.rb&lt;br/&gt;hello&lt;br/&gt;hello&lt;br/&gt;hello&lt;/i&gt;&lt;br/&gt;&lt;br/&gt;While little known, this project has been under active development for one year and eight months. I started the project around mid 2005, and it took me about eight months to write a ruby parser with Antlr, and then one year to implement the compiler and runtime. Some people joined me during the second half of 2006 and made great contribution. It is just the beginning of an exciting journey.&lt;br/&gt;&lt;br/&gt;We still have a long way to go before claiming XRuby is a very competent alternative implementation of ruby. And comparing with our peers we lag behind in implementing ruby's built-in libraries and do not have Ruby-Java bridge. Our next focus is to improve this situation and make major ruby libraries and framework work under XRuby. And we hope by end of 2007 you can use XRuby to compile your Ruby On Rails application to a .war file and run it directly on a J2EE server. &lt;br/&gt;&lt;br/&gt;We appreciate your feedback. Our development maillist is at:&lt;br/&gt;&lt;a href="http://groups.google.com/group/xruby-devel"&gt;http://groups.google.com/group/xruby-devel&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;I also setup a new blog to be used as XRuby's team blog: &lt;a href="http://xruby.blogspot.com/"&gt;http://xruby.blogspot.com&lt;/a&gt; . While  new articles will be cross posted for quite a while, I encourage you to subscribe &lt;a href="http://feeds.feedburner.com/xruby"&gt;http://feeds.feedburner.com/xruby &lt;/a&gt;if have not done so.&lt;br/&gt;&lt;br/&gt;Thank you and have fun.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-312769520467144627?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/01/xruby-010-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-2715483769101644330</guid><pubDate>Tue, 02 Jan 2007 16:45:00 +0000</pubDate><atom:updated>2007-01-02T09:12:44.490-08:00</atom:updated><title>XRuby 0.1.0 will be released in January, 2007</title><description>Well, the release date of xruby 0.1.0  (our first release) has to be pushed back a little due to the lack of time of our projects members.&lt;br/&gt;&lt;br/&gt;The goal of the xruby 0.1.0 is to pass all the tests in ruby's sample\test.rb,  and we are very close to the goal. Right now we still have a few failed tests to be fixed, the majority of them are serialization (Array#pack, Marshal) and eval related.  Most technical obstacles of compiling ruby have been solved, it just takes time to do the implementation (especially for the large amount of builtin libraries).&lt;br/&gt;&lt;br/&gt;2007 is going to be an exciting year:)&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt; &lt;style&gt;&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-2715483769101644330?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2007/01/xruby-010-will-be-released-in-january.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-116171439809318822</guid><pubDate>Tue, 24 Oct 2006 18:05:00 +0000</pubDate><atom:updated>2006-12-21T14:08:34.886-08:00</atom:updated><title>XRuby Hacking Guide on wiki</title><description>Update 12/20/2006: As &lt;a href="http://google-code-updates.blogspot.com/2006/12/happy-holidays-open-source-developers.html"&gt;Google Code now provides Wiki by itself&lt;/a&gt;, I just move the project wiki over there as it is better integrated.&lt;br /&gt;&lt;br /&gt;Update 12/21/2006: Oops, now I regret what I did...Google Code only allow project members and owners add and edit wiki pages, which make it almost useless.&lt;br /&gt;&lt;br /&gt;Right now the only document we have is &lt;a href="http://code.google.com/p/xruby/wiki/XRubyHackingGuide"&gt;XRuby Hacking Guide&lt;/a&gt;. The goal of this guide is to help users/developers understand XRuby's implementation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-116171439809318822?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/10/xruby-hacking-guide-on-wiki.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-115791288118067817</guid><pubDate>Sun, 10 Sep 2006 17:51:00 +0000</pubDate><atom:updated>2006-09-10T11:47:31.796-07:00</atom:updated><title>XRuby project is now hosted on Google Code</title><description>XRuby is an open source Ruby compiler which compiles Ruby source code (.rb) to Java bytecode (.class). On last Friday I moved the source code from my local Subversion server to Google Code(&lt;a href="http://code.google.com/p/xruby"&gt;code.google.com/p/xruby/&lt;/a&gt;), so the project is now public available (GPL license).&lt;br /&gt;&lt;br /&gt;Although I have never announced this project, I have been working on it for more than one year. This February I &lt;a href="http://seclib.blogspot.com/2006/02/first-release-of-rubyfront.html"&gt;made the parser public available&lt;/a&gt;, now the main effort is on the compiler backend (java bytecode generation). I expect to release the first stable version at the end of 2006.&lt;br /&gt;&lt;br /&gt;So far I am not very satisfied with my progress. I have a busy day job which has nothing related to Ruby and Java, so can only manage to work on XRuby about one hour a day(except weekends and holidays). When I started the project I thought XRuby is going to be the first ruby compiler in the world. But now &lt;a href="http://plas.fit.qut.edu.au/Ruby.NET/"&gt;Gardens Point Ruby.NET&lt;/a&gt; has released their first alpha version, and I expect JRuby will start to do their compiler in a few months (since &lt;a href="http://www.tbray.org/ongoing/When/200x/2006/09/07/JRuby-guys"&gt;they have been hired by Sun to work on JRuby full time&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Anyway, the project gives me lots of fun and the implementation starts to gain momentum. It looks very promising to see the first stable release around this new year, stay tuned:)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-115791288118067817?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/09/xruby-project-is-now-hosted-on-google.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-115514731519460891</guid><pubDate>Wed, 09 Aug 2006 17:37:00 +0000</pubDate><atom:updated>2006-09-12T12:07:00.903-07:00</atom:updated><title>Operator overloading in ruby</title><description>Most operators in ruby (e.g. &lt;i&gt;+, -, *, /, %&lt;/i&gt; etc) are actually method calls, and they can be overloaded just like other method calls. But unlike C++, Ruby does not have operators like &lt;i&gt;+=, -=, *=, /=&lt;/i&gt; etc, so &lt;b&gt;a += 1&lt;/b&gt; is translated directly to &lt;b&gt;a = a + 1&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;This involves some performance penalty in some cases, for example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a1 = [1, 2, 3]&lt;br /&gt;a2 = [4, 5, 6]&lt;br /&gt;a1 += a2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Behind the scenes, a new array is created (as a1 += a2 is equivalent to a1 = a1 + a2, operator + will create a new array, then a1 is assigned to hold the reference to the new array, and the old a1 will be garbage collected). If you just want to append a2 to a1, the following code is a little bit more efficient:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a1.concat(a2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;concat method will directly update the content of a1 without creating a new array.&lt;br /&gt;&lt;br /&gt;And it is surprising to know that not all ruby's operators are method calls, so you can not overload &lt;i&gt;!, not, &amp;&amp;, and, ||, or&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;UPDATE 09/12/2006: Chris pointed out an error in my original article(I shouldn't use &lt;&lt; operator as the alternative of +=), see comments for details. Thanks,  Chris!&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;[1]&lt;a href="http://www.rubycentral.com/faq/rubyfaq-7.html#ss7.2"&gt;Are +, -, * ... operators?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-115514731519460891?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/08/operator-overloading-in-ruby.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-114642798657017194</guid><pubDate>Sun, 30 Apr 2006 19:15:00 +0000</pubDate><atom:updated>2006-04-30T13:24:53.226-07:00</atom:updated><title>Rubyfront 0.2.0 released</title><description>This new version of Rubyfront fixed a bug found when parsing Ruby on Rails 1.1.2. You can &lt;a href="http://xruby.com/Documents/rubyfront.zip"&gt;download the source code from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In rubyfront 0.2.0, I changed the way it handles &lt;a href="http://www.ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#exprsub"&gt;expression substitution&lt;/a&gt;. The older versions of rubyfront ignores the content in expression substitution. For example, if the input is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;"hello, #{name}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The lexer will first start to scan the input as a double quote string. After it sees "#{", it will go find the first '}' and think that is the end of the expression substitution. Unfortunately, expression substitution may contain '}' itself. For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;"begin #{1.times {"block"}} end"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The lexer can not match the above input as one string. Expression substitution can contain any legal ruby program (compoundStatement), and only the parser understands the structure.&lt;br /&gt;&lt;br /&gt;To correctly handle this situation, the new lexer will suspend its state when the start of expression substitution is seen (only 'begin ' is matched so far). After the parser finishes its processing of expression substitution, it will notify the lexer and the lexer will resume its state and matches the rest of the string (' end').&lt;br /&gt;&lt;br /&gt;Btw, when you run parser smoke test against Ruby on Rails 1.1.2, you will see the following failures:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\Documents and Settings\xxx\workspace\rubyfront&gt;build parsersmoketest&lt;br /&gt;&lt;...&gt;&lt;br /&gt;parsersmoketest:&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\activerecord-1.14.2\test\connections\native_sqlite3\in_memory_connection.rb: line 18:76: expecting EOF, found ')'&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\environments\environment.rb: line 8:1: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\controller\templates\controller.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\controller\templates\functional_test.rb: line 1:41: unexpected token: ..&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\controller\templates\helper.rb: line 1:8: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\integration_test\templates\integration_test.rb: line 3:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\mailer\templates\mailer.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\mailer\templates\unit_test.rb: line 4:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\migration\templates\migration.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\model\templates\migration.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\model\templates\model.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\model\templates\unit_test.rb: line 1:41: unexpected token: ..&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\plugin\templates\generator.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\plugin\templates\unit_test.rb: line 3:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\scaffold\templates\controller.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\scaffold\templates\functional_test.rb: line 5:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\scaffold\templates\helper.rb: line 1:8: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\session_migration\templates\migration.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\web_service\templates\api_definition.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\web_service\templates\controller.rb: line 1:7: unexpected token: &lt;&lt;br /&gt;     [java] parser exception for C:\ruby\lib\ruby\gems\1.8\gems\rails-1.1.2\lib\rails_generator\generators\components\web_service\templates\functional_test.rb: line 1:41: unexpected token: ..&lt;br /&gt;     [java] 2428 ruby programs have been parsed, 21 failed.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Those errors are expected as those files are in .rhtml format (not valid ruby, ROR requires erb to preprocess them).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-114642798657017194?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/04/rubyfront-020-released.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-114532508004961452</guid><pubDate>Tue, 18 Apr 2006 01:49:00 +0000</pubDate><atom:updated>2006-04-30T12:15:11.443-07:00</atom:updated><title>Compile-time type inference for ruby has its limit</title><description>I have been thinking about doing type inference at compiler time for ruby. Whiles lots of the cases can be handled in a straightforward way, type inference won't work in all situations.&lt;br /&gt;&lt;br /&gt;One of the problems is, ruby supports multiple return types:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def f&lt;br /&gt;  if rand(2) == 1&lt;br /&gt;       return 1&lt;br /&gt;  else&lt;br /&gt;       return "hello"&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above code, method 'f' will randomly return 1 (Fixnum) or "hello" (String). At compiler time there is no way for a compiler to know what type to return. All it can do is to insert meta data so that typing checking can be done at runtime.&lt;br /&gt;&lt;br /&gt;And multiple return types is not uncommon in real code. For example, Ruby' s array or hash can hold objects of different types:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  a = [1, 1.5, "hello"]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above code, Array 'a' contains three different types of objects: Fixnum, Float and String. And element reference("[]") is an example of method that has multiple return types.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-114532508004961452?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/04/compile-time-type-inference-for-ruby.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-114015291498261682</guid><pubDate>Fri, 17 Feb 2006 04:55:00 +0000</pubDate><atom:updated>2006-04-30T12:14:53.660-07:00</atom:updated><title>First release of Rubyfront</title><description>&lt;b&gt;UPDATE 02/27/2006: a new version of rubyfront was released, and now it is capable to parse ruby's stable snapshot and Ruby on Rails. Thanks Mauricio Fernandez for reporting the bugs.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I am glad to announce the first release of rubyfront (a &lt;a href="http://www.ruby-lang.org"&gt;ruby&lt;/a&gt; parser powered by &lt;a href="http://www.antlr.org"&gt;antlr&lt;/a&gt;), you can &lt;a href="http://xruby.com/Documents/rubyfront.zip"&gt;download it here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;br /&gt;The goal of this project is to create an error checking tool for ruby. Currently we are using antlr as the parser generator and java as the implementation language.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Current Status&lt;/b&gt;&lt;br /&gt;Even though Rubyfront is in its very early stage, the current parser can accept the entire ruby standard library. So far the parser only do error checking at syntax level, no semantic checking is implemented. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What's next&lt;/b&gt;&lt;br /&gt;We will focus on improving the parser to make it closer to C ruby's yacc counterpart.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Requirement&lt;/b&gt;&lt;br /&gt;J2SE 5.0 and up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Demonstration&lt;/b&gt;&lt;br /&gt;1. Open build.xml and change "rubycode.dir" to the directory of your ruby source code.&lt;br /&gt;2. Run the smoke test. On windows, you can simply type "build parsersmoketest".&lt;br /&gt;&lt;br /&gt;For example, if you have Ruby 1.8.4's source code installed on "c:\ruby", you are going to see the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;parsersmoketest:&lt;br /&gt; [java] 1574 ruby programs have been parsed, 0 failed.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above result shows that all 1574 ruby programs are accepted by the parser.&lt;br /&gt;&lt;br /&gt;By the way, if you run smoke test against Ruby's windows One-Click installer, you are going to see a few failures from fxruby 1.2.6 and others. The good news is: they are known to be broken (You can use "ruby -c" to verify). If you have Ruby on Rails installed, you are going to see more failures. But all of the them are expected, since those are actually .rhtml files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-114015291498261682?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/02/first-release-of-rubyfront.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-113682550193628710</guid><pubDate>Mon, 09 Jan 2006 16:51:00 +0000</pubDate><atom:updated>2006-01-09T08:51:42.166-08:00</atom:updated><title>Ruby interpreter crashes with invalid input</title><description>Last week I found a bug in ruby's parser, NULL pointer reference will happen when the following program is parsed:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\ruby-1.8.4-i386-mswin32\bin&gt;ruby -e 'def a=.a=;end'&lt;br /&gt;-e:1: identifier a= is not valid&lt;br /&gt;-e:1: [BUG] Segmentation fault ruby 1.8.4 (2005-12-24) [i386-mswin32]&lt;br /&gt;This application has requested the Runtime to terminate it in an unusual way.&lt;br /&gt;Please contact the application's support team for more information.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now it was fixed in CVS.&lt;br /&gt;&lt;br /&gt;This is not a serious security problem. I tried to find if it will result in a remote DOS vulnerability in Ruby on Rails, but find nothing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-113682550193628710?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/01/ruby-interpreter-crashes-with-invalid.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-113657207973442389</guid><pubDate>Fri, 06 Jan 2006 17:58:00 +0000</pubDate><atom:updated>2006-01-06T10:32:31.326-08:00</atom:updated><title>Why "undef" is keyword in ruby</title><description>&lt;a href="http://www.ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#undef"&gt;undef&lt;/a&gt; is a &lt;a href="http://www.ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#resword"&gt;keyword&lt;/a&gt; in ruby. But its syntax:&lt;br /&gt;"undef method-name (, method-name)*", looks just like a normal command call (function call without parameter, e.g. print "hello"). Then why not just implement it as a built-in method? As we know, "private", "protected" and "public", which are keywords in lots of other language, are &lt;a href="http://seclib.blogspot.com/2005/10/access-control-for-ruby-class.html"&gt;just implemented as plain method in ruby&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What makes "undef" special is in attribute methods. In ruby we can define method like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class A&lt;br /&gt;&amp;nbsp;&amp;nbsp;def a=(value)  &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@value = value  &lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And later, we can undefine "a=" with "undef":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;undef a=&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;"a=" is not a valid identifier(because of the '=') unless the parser is expecting a method name, for example, after "alias", "def" or "undef".&lt;br /&gt;&lt;br /&gt;Note ":a=" is valid &lt;a href="http://www.rubycentral.com/faq/rubyfaq-6.html#ss6.1"&gt;symbol&lt;/a&gt;. "private", "protected" and "public" are normal methods since they only accept symbols:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class MyClass&lt;br /&gt;&lt;br /&gt;&amp;nbsp;  def method1&lt;br /&gt;&amp;nbsp;  end&lt;br /&gt;&lt;br /&gt;&amp;nbsp;  public :method1&lt;br /&gt;&amp;nbsp; #This is invalid: public method1&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since "undef" is followed by method name, it has to be implemented as a keyword, so the parser/lexer knows when to change its state to accept the extra '='.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-113657207973442389?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2006/01/why-undef-is-keyword-in-ruby.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-113476711658709728</guid><pubDate>Fri, 16 Dec 2005 18:48:00 +0000</pubDate><atom:updated>2005-12-18T10:08:18.506-08:00</atom:updated><title>MiniRails</title><description>Lots of people are using web technologies in their desktop applications, and it is especially common to find a windows application which embeds &lt;a href="msdn.microsoft.com/workshop/ browser/WebBrowser/WebBrowser.asp"&gt;WebBrowser control&lt;/a&gt; to render great GUI elements. There are some bumps, for example, you can not do disk/socket IO with javascript(even java applet), which most applications have to reply on.&lt;br /&gt;&lt;br /&gt;To overcome this, we can either use ActiveX control(I am using it myself and am satisfied with it), or launch a web server on the background. The second has an additional advantage: the server and client are decoupled, so in the future you can easily migrate to a pure web environment without touching too much code. While this approach looks attractive, however, we have to face a reality: most web application servers can be too big for most desktop applications to distribute. Note I am taking web application servers here, not simple web servers. It is easy to find a small footprint web server or even write one by yourself, but your development style will have to go back to the 80s (CGI in C). Even though &lt;a href="http://www.onjava.com/pub/a/onjava/2002/04/03/tomcat.html"&gt;Tomcat Embedded&lt;/a&gt; 5.5.12 can be downloaded as a 3.1 MB zip file, your customers may not have JVM installed in the first place. &lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/01/cuttingedge/"&gt;Cassini&lt;/a&gt; suffers the same problem, Microsoft has not pushed hard enough to make .NET universal.&lt;br /&gt;&lt;br /&gt;How about the &lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt;? It turns out to be a great choice. While a complete distribution takes lots of disk space, it is easy to customize so that we only ship what we need.&lt;br /&gt;&lt;br /&gt;Here is how I build my minimum ruby distribution that rail can run on(use windows as example):&lt;br /&gt;&lt;br /&gt;1. Have &lt;a href="http://rubyforge.org/FRS/?group_id=167"&gt;ruby&lt;/a&gt; installed to C:\ruby. Later we need to copy files from it.&lt;br /&gt;&lt;br /&gt;2. Download rails &lt;a href="http://rubyforge.org/frs/?group_id=307"&gt;stand-alone packages&lt;/a&gt;, uncompress it to C:\rails, and empty doc/ folder to save space.&lt;br /&gt;&lt;br /&gt;3. Copy ruby.exe and msvcrt-ruby18.dll from C:\ruby\bin to C:\rails.&lt;br /&gt;&lt;br /&gt;4. Copy the following OS independent libraries (implemented in pure ruby) from C:\ruby\lib\ruby\1.8 to C:\rails\lib\ruby\1.8:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; base64.rb&lt;br /&gt; benchmark.rb&lt;br /&gt; cgi.rb and cgi/&lt;br /&gt; date.rb&lt;br /&gt; date/format.rb&lt;br /&gt; delegate.rb&lt;br /&gt; drb.rb and drb/&lt;br /&gt; e2mmap.rb&lt;br /&gt; erb.rb&lt;br /&gt; English.rb&lt;br /&gt; fileutils.rb&lt;br /&gt; ipaddr.rb&lt;br /&gt; irb.rb and irb/&lt;br /&gt; kconv.rb&lt;br /&gt; logger.rb&lt;br /&gt; mutex_m.rb&lt;br /&gt; net/http.rb&lt;br /&gt; net/protocol.rb&lt;br /&gt; net/smtp.rb&lt;br /&gt; observer.rb&lt;br /&gt; optparse.rb and optparse/&lt;br /&gt; parsedate.rb&lt;br /&gt; pathname.rb&lt;br /&gt; pstore.rb&lt;br /&gt; rational.rb&lt;br /&gt; rexml.rb and rexml/&lt;br /&gt; set.rb&lt;br /&gt; singleton.rb&lt;br /&gt; soap.rb and soap/&lt;br /&gt; tempfile.rb&lt;br /&gt; thread.rb&lt;br /&gt; time.rb&lt;br /&gt; timeout.rb&lt;br /&gt; tmpdir.rb&lt;br /&gt; uri.rb and uri/&lt;br /&gt; webrick.rb and webrick/&lt;br /&gt; xmlrpc/&lt;br /&gt; xsd/&lt;br /&gt; yaml.rb and yaml/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Copy the following OS dependent libraries from C:\ruby\lib\ruby\1.8\i386-mswin32 to C:\rails\lib\ruby\1.8\i386-mswin32:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; digest.so&lt;br /&gt; digest/md5.so&lt;br /&gt; digest/sha1.so &lt;br /&gt; fcntl.so&lt;br /&gt; nkf.so&lt;br /&gt; rbconfig.rb&lt;br /&gt; socket.so&lt;br /&gt; strscan.so&lt;br /&gt; stringio.so&lt;br /&gt; syck.so&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. Now we may still need a database (optional). Here is how I get sqlite3 installed:&lt;br /&gt;a) Download &lt;a href="http://www.sqlite.org/download.html"&gt;precompiled binaries&lt;/a&gt;. Copy sqlite3.exe and sqlite3.dll into C:\rails folder.&lt;br /&gt;b) Download &lt;a href="http://rubyforge.org/frs/?group_id=254"&gt;SQLite-Ruby&lt;/a&gt;. Copy sqlite3_api.so to C:\rails\lib\ruby\site_ruby\1.8\i386-msvcrt\,  copy sqlite3.rb and sqlite3/ to C:\rails\lib\ruby\site_ruby\1.8&lt;br /&gt;That's it! You can start WEBrick now:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\rails&gt;ruby script\server&lt;br /&gt;=&gt; Booting WEBrick...&lt;br /&gt;=&gt; Rails application started on http://0.0.0.0:3000&lt;br /&gt;=&gt; Ctrl-C to shutdown server; call with --help for options&lt;br /&gt;[2005-12-16 15:23:09] INFO  WEBrick 1.3.1&lt;br /&gt;[2005-12-16 15:23:09] INFO  ruby 1.8.2 (2004-12-25) [i386-mswin32]&lt;br /&gt;[2005-12-16 15:23:09] INFO  WEBrick::HTTPServer#start: pid=440 port=3000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And do whatever rails developement as you want.&lt;br /&gt;&lt;br /&gt;This distribution takes 6.28M on disk. If you zip it, it shrinks to a 2.3M file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-113476711658709728?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2005/12/minirails.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-10398581.post-113451991329352684</guid><pubDate>Tue, 13 Dec 2005 23:55:00 +0000</pubDate><atom:updated>2006-01-30T14:52:56.416-08:00</atom:updated><title>Good experience with boost memory pool</title><description>With increasing number of source code to compile, the compiler I maintain becomes unacceptable slow. After profiling the code with &lt;a href="http://www.automatedqa.com/products/aqtime/"&gt;AQTime&lt;/a&gt;, I found about 30% percent CPU is used by malloc(), and half of them are for tree node allocation(fixed size).&lt;br /&gt;&lt;br /&gt;After &lt;a href="http://seclib.blogspot.com/2005/12/compare-performance-of-malloc-and.html"&gt;testing the performance of boost memory pool&lt;/a&gt;, I simply replaced malloc() with boost::object_pool::malloc().  The result is great, it almost eliminated the cost of tree node allocation. The total amount of time used for malloc is down to 13%. Still plenty of room for improvement, but the performance is at least acceptable.&lt;br /&gt;&lt;br /&gt;There is one thing to remember: boost::object_pool is designed for "allocate many objects and then destroy all of them" type of scenario, so freeing memory from the pool can be very slow. For example, at the beginning I also replaced free() with boost::object_pool::free(), which make the performance even worse: boost::simple_segregated_storage&lt;unsigned int&gt;::find_prev() and boost::simple_segregated_storage&lt;unsigned int&gt;::nextof() start to take over all the CPU. So I do not do free anymore and simply let ~object_pool() to release the memory. This works perfect for my compiler, but may not be good for other applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10398581-113451991329352684?l=seclib.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://seclib.blogspot.com/2005/12/good-experience-with-boost-memory-pool.html</link><author>noreply@blogger.com (xue.yong.zhi)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item></channel></rss>