<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Xblog: Tag smalltalk</title>
    <link>http://xblog.xman.org/articles/tag/smalltalk</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>hey, if it has a capital X in it, it has to be great!</description>
    <item>
      <title>Ruby on... Gemstone?</title>
      <description>&lt;p&gt;Really, when you think about it, how can a company called Gemstone NOT get involved with a language called Ruby. So, Gemstone, of Gemstone and &lt;a href="http://seaside.gemstone.com/" title="GLASS"&gt;GLASS&lt;/a&gt; fame, &lt;a href="http://www.infoq.com/news/2008/04/maglev-gemstone-builds-ruby"&gt;have apparently decided to get the traditionally lackadaisical Ruby runtime running on their VM&lt;/a&gt;. From the first time I dabbled with Ruby it seemed like &amp;#8220;file-based Smalltalk with some ugly Perl-isms and a crappy VM&amp;#8221; (and yes, in fairness, the ugly Perl-isms are also part of its strength), so this makes a lot of sense, and may yet drag Ruby in to the real world. &lt;strike&gt;Gemstone gets bonus points for providing yet another example of &lt;a href="http://ruby.gemstone.com/" title="MagLev"&gt;confusing efficiency with scalability&lt;/a&gt;.&lt;/strike&gt;&lt;/p&gt;

&lt;p&gt;BTW: &lt;a href="http://mike.nu/"&gt;Mike&lt;/a&gt; came up with a great acronym for Gemstone to use: GLARE: &amp;#8220;Gemstone Linux Apache and Ruby Emulation&amp;#8221;.&lt;/p&gt;

&lt;p&gt;UPDATE: Avi caught me red handed for not reading the &lt;em&gt;entire&lt;/em&gt; interview. Upon further reading of the interview and &lt;a href="http://www.avibryant.com/2008/03/ive-had-a-numbe.html" title="Ruby and other gems"&gt;Avi&amp;#8217;s excellent blog posting comparing Gemstone to Rails&lt;/a&gt;, it appears the Gemstone folks are very much talking about scalability as opposed to efficiency. In fact, it seems they are expecting the primary advantage of MagLev to be through Gemstone&amp;#8217;s persistence architecture (here&amp;#8217;s hoping it is &lt;em&gt;also&lt;/em&gt; a lot more efficient).&lt;/p&gt;</description>
      <pubDate>Wed, 30 Apr 2008 16:02:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:19a04752-3b6b-4204-8a7d-4b07a4b103af</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2008/04/30/ruby-on-gemstone</link>
      <category>Programming</category>
      <category>ruby</category>
      <category>smalltalk</category>
      <category>efficiency</category>
      <category>scalability</category>
      <category>gemstone</category>
      <category>maglev</category>
    </item>
    <item>
      <title>SCALE and Zumastore</title>
      <description>&lt;p&gt;I&amp;#8217;m spending this weekend at &lt;a href="http://socallinuxexpo.com/scale5x/ Southern California Linux Expo"&gt;SCALE&lt;/a&gt;. As always, the conference is great, and better than the year before. The talks are spilling out in to the halls, often multiple talks at a time (right now Chris DiBona&amp;#8217;s talk has so many people attending and the spill over is so great, that it makes more sense to catch the mp3 of it at a later date).&lt;/p&gt;

&lt;p&gt;One of the coolest things so far was my friend Daniel Phillips&amp;#8217; announcement of the &lt;a href="http://zumastor.blogspot.com/" title="Zumastore"&gt;Zumastor project&lt;/a&gt;. It looks like this Google sponsored open source project is finally going to give Network Appliances some real open source competition.&lt;/p&gt;

&lt;p&gt;I was intrigued by a presentation on &lt;a href="http://sourceware.org/systemtap/" title="SystemTap"&gt;SystemTap&lt;/a&gt;. This is the first system I&amp;#8217;ve seen that looks like it can give &lt;a href="http://www.sun.com/bigadmin/content/dtrace/" title="DTrace"&gt;DTrace&lt;/a&gt; a run for the money, and most importantly it runs on Linux. It isn&amp;#8217;t all there yet, but it&amp;#8217;s close enough I&amp;#8217;m going to start playing with it.&lt;/p&gt;

&lt;p&gt;I was also impressed to see the &lt;a href="http://www.squeak.org/" title="Squeak"&gt;Squeak&lt;/a&gt; folks making an appearance, both with a booth and a BoF later tonight. Looks like that project still has a decent amount of momentum.&lt;/p&gt;

&lt;p&gt;Sun had a presentation talking about their open source stack (software and hardware). It was fun listening to just how much Sun gets the message that just five years ago I thought was falling on deaf ears there. It was also neat seeing a graph from a study that was done showing who was contributing to open source. Sun is the clear leader in terms of the amount of code and total man hours they&amp;#8217;ve contributed (multiples of what most others have done). People don&amp;#8217;t always grok that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: Found the &lt;a href="http://ec.europa.eu/enterprise/ict/policy/doc/2006-11-20-flossimpact.pdf" title="Economic Impact of Open Source Software On Innovation and Competitiveness of the Information and Communications Technologies of the European Union"&gt;study on who contributes to open source&lt;/a&gt;. Thanks to &lt;a href="http://blogs.sun.com/mingenthron" title="Matt Ingenthron's Stream of Consciousness"&gt;Matt Ingenthron&lt;/a&gt; (who did the presentation at SCALE) for getting me a pointer even before his slides make it out to the SCALE web site.&lt;/p&gt;</description>
      <pubDate>Sun, 11 Feb 2007 14:08:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:9a84e472-3ef6-4e93-a0f2-832390770ad6</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2007/02/11/scale-and-zumastore</link>
      <category>Programming</category>
      <category>smalltalk</category>
      <category>linux</category>
      <category>open</category>
      <category>source</category>
      <category>dtrace</category>
      <category>scale</category>
      <category>conference</category>
      <category>zumastore</category>
      <category>systemtap</category>
      <category>chris</category>
      <category>dibona</category>
      <category>squeak</category>
      <category>Sun</category>
      <trackback:ping>http://xblog.xman.org/articles/trackback/1488</trackback:ping>
    </item>
    <item>
      <title>problem isVisualWorks ifFalse: [Gentoo]</title>
      <description>&lt;p&gt;After posting about &lt;a href="http://xblog.xman.org/articles/2006/09/10/cincom-smalltalk-glibc-2-4-hang" title="Cincom Smalltalk + glibc 2.4 == hang"&gt;my problems getting Cincom Smalltalk to work on my Gentoo system&lt;/a&gt;, I recevied an impressive amount of help. Aside from my friend the committed Smalltalker, I also received help from Isaac Gouy (who was able to quickly demonstrate that Cincom worked just fine with glibc 2.4), and most impressively James Robertson, the product manager for Cincom Smalltalk. I got all this help despite being too lazy to post to the appropriate mailing list or contact Cincom&amp;#8217;s technical support. It&amp;#8217;s nice to know the product is supported this fervently.&lt;/p&gt;

&lt;p&gt;I sent Mr. Robertson my strace, showing VisualWorks doing the mmap() tango indefinitely. However, he had asked for a core file and I realized I didn&amp;#8217;t have one. So, I set about creating one for him. I adjusted ulimit and launched VisualWorks&amp;#8230;. and it just worked!&lt;/p&gt;

&lt;p&gt;The main thing that has changed since the last time I launched it was that Gentoo had an update to glibc, so while I have no concrete evidence (which obviously didn&amp;#8217;t prevent me from pointing an accusatory finger in VisualWork&amp;#8217;s direction ;-), my prime suspect is some kind of bug in Gentoo&amp;#8217;s glibc.&lt;/p&gt;

&lt;p&gt;Honestly, I&amp;#8217;m just happy to have VisualWorks working on my system, and my general laziness will prevent me from investigating this further. It is snappier and generally more consistent with the rest of my development tools, so it&amp;#8217;s much more fun to work with than Squeak.&lt;/p&gt;

&lt;p&gt;Don&amp;#8217;t get me wrong: I still really like Squeak, and in particular I like how it is open sourced, but Squeak&amp;#8217;s UI really annoys the heck out of me, and I really do prefer to have VisualWork&amp;#8217;s more efficient runtime. At some point I&amp;#8217;ll be annoyed by Cincom not being truly open source, but for now I&amp;#8217;m enjoying it tremendously.&lt;/p&gt;</description>
      <pubDate>Sun, 01 Oct 2006 19:23:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3c192424-1c6b-40ab-b931-40b51de86b52</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2006/10/01/problem-isvisualworks-iffalse-gentoo</link>
      <category>Programming</category>
      <category>smalltalk</category>
      <category>cincom</category>
      <category>glibc</category>
      <category>gentoo</category>
      <trackback:ping>http://xblog.xman.org/articles/trackback/248</trackback:ping>
    </item>
    <item>
      <title>Ruby On Nails Scratching a Chalkboard</title>
      <description>&lt;p&gt;So, as I explore how Ruby works, I&amp;#8217;m discovering some bits of ugliness.
It&amp;#8217;s syntax is increasingly reminding me more of Perl than Smalltalk. A
case in point: blocks.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d heard so much about Ruby&amp;#8217;s Smalltalkishness that I was a bit taken
aback when I saw control statements in the language grammar. In
Smalltalk, control flow is managed using methods and blocks, and I knew
Ruby had blocks (this is one of the things that you hear so much about
in &lt;a title="Beyond Java, by Bruce Tate" href="http://www.oreilly.com/catalog/beyondjava/"&gt;Beyond Java&lt;/a&gt;), so why did they need these control statements?
In Smalltalk, control flow looks like this:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;1 + 1 = 2
  ifTrue: ['it is true']
  ifFalse: ['it is false']&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, I can&amp;#8217;t claim that this provides any real productivity boost over Ruby&amp;#8217;s approach:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;it is true&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;it is false&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But I was kind of surprised, given Ruby&amp;#8217;s ties to Smalltalk, that someone hadn&amp;#8217;t hacked it in. So, I went about hacking it in myself. That&amp;#8217;s when I found out why.&lt;/p&gt;

&lt;p&gt;It turns out that blocks in Ruby have a very high level of syntactic sugariness. Not only do they have their own special literal form (which is a key advantage over say Java&amp;#8217;s Inner Classes, or C++ functors without boost::lambda), but they also have their own special status which really makes them non-objects. (I found it amusing to discover that the most non-object entity in Ruby is a block).&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the magic: blocks aren&amp;#8217;t passed as normal parameters to functions. They are passed through an implicit variable (showcasing Ruby&amp;#8217;s Perlishness here). So, if, for example, I wanted to add something like Smalltalk&amp;#8217;s ifTrue: to Ruby, I&amp;#8217;d do the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TrueClass&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ifTrue&lt;/span&gt;
      &lt;span class="keyword"&gt;yield&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;FalseClass&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ifTrue&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;ifTrue&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Math works&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;ifTrue&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Math is broken&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that ifTrue doesn&amp;#8217;t appear to take any parameters, and neither does the &amp;#8220;yield&amp;#8221; method. In reality, the block is an implicit parameter. One Ruby tutorial claimed this is a good thing, because it means that all Ruby methods can take a block as a parameter&amp;#8230;. even if they don&amp;#8217;t use it. Me, I&amp;#8217;m a big fan of explicitness, but I can see that in a scripting world, sometimes these kind of shortcuts are nice to have. What&amp;#8217;s bad about this is that not only does it mean that all Ruby methods can take a block as a parameter, it also means all Ruby methods can only take &lt;em&gt;exactly one block&lt;/em&gt; as a parameter, and it has to be the last one.&lt;/p&gt;

&lt;p&gt;Now, it turns out that Ruby has a wrapper around blocks called Proc, which lets you treat a block like a real object, Of course, it has all the syntactic beauty of Java&amp;#8217;s Inner Classes. Here&amp;#8217;s how you can do ifTrueifFalse in Ruby:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TrueClass&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ifTrueIfFalse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;trueProc&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;falseProc&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="constant"&gt;trueProc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;FalseClass&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ifTrueIfFalse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;trueProc&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;falseProc&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="constant"&gt;falseProc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;ifTrueIfFalse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Proc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Math works&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;},&lt;/span&gt;&lt;span class="constant"&gt;Proc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Math is broken&lt;/span&gt;&lt;span class="punct"&gt;'})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But wait! There&amp;#8217;s more! Since Proc&amp;#8217;s are proper objects, you can query them for meta-information, which is really handy for various dynamic programming tricks. Only&amp;#8230; Ruby&amp;#8217;s interface is kind of weird. Proc&amp;#8217;s have this method &amp;#8220;arity&amp;#8221; which tells you how many arguments the block takes&amp;#8230; sort of. For reasons passing understanding, if a block takes zero arguments, the function returns &amp;#8220;-1&amp;#8221; intead of &amp;#8220;0&amp;#8221;, and if it takes 1 argument, it returns &amp;#8220;-2&amp;#8221; instead of &amp;#8220;1&amp;#8221;. So, now we&amp;#8217;ve established that it can never return 0 or 1, and that you can&amp;#8217;t always use the return value as an collection size for your argument list. Here&amp;#8217;s where it gets really crazy though: if your function takes a variable argument list with it&amp;#8217;s last parameter, arity returns &amp;#8220;0 - # of args&amp;#8221;. So, quick question for you: if arity returns back -2, does that mean it&amp;#8217;s argumetn list is one argument long, or that it takes one argument followed by a variable list of arguments? I&amp;#8217;m not sure how Bruce Tate can claim that Ruby doesn&amp;#8217;t have some weird anachronisms that get in the way of doing metaprogramming with a straight face.&lt;/p&gt;

&lt;p&gt;In fairness, the case where you want to pass a single block as your last argument seems like the common case, and Ruby is a scripting language after all. I&amp;#8217;m mostly annoyed because I&amp;#8217;ve heard so many people talk about Ruby&amp;#8217;s elegance, comparing it favourably with Smalltalk (which admittedly is not entirely without warts). Upon inspection it seems to have warts just like other languages (well, some languages have a few more warts than others). Still, there is hope. Ruby does seem to have some genuinely nice features, and it is open source, so there is always the possibility that some of these idiosyncracies will get cleaned up in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; So, someone with some real Ruby experience has clarified for me that nobody actually does &amp;#8220;Proc.new&amp;#8221; in Ruby. Instead they use Lambda. So, invoking my ifTrueIfFalse method would normally be done like so:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;ifTrueIfFalse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Math Works&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;},&lt;/span&gt;&lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{'&lt;/span&gt;&lt;span class="string"&gt;Math Doesn&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="constant"&gt;Work&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt; })&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which I have to admit does seem a lot prettier for some reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ANOTHER UPDATE:&lt;/strong&gt; I&amp;#8217;ve gotten some great comments to this article, and I thought I should incorporate their content. First, people have suggested that you can break up ifTrueIfFalse in to two calls that are chained together, and then get back some of the elegance. I thought about this when I first looked in to it, but you lose the ability to pick up a return object cleanly.&lt;/p&gt;

&lt;p&gt;Antti Tarvainen provided some excellent points. In particular he clarified the difference between a Proc that takes no arguments (arity returns 0) and a Proc that doesn&amp;#8217;t define any arguments returns -1. Furthermore, arity has been &lt;a href="http://ruby-doc.org/core/classes/Proc.src/M000808.html" title="Proc in Ruby 1.9"&gt;updated for Ruby 1.9&lt;/a&gt; to what seems like a more sensible behavior. I noticed that even in 1.8 &lt;pre&gt;puts lambda {|a|}.arity&lt;/pre&gt; returns 1, which suggests the Ruby documentation is a wee bit out of date.&lt;/p&gt;

&lt;p&gt;I still think it&amp;#8217;d be far more sensible to not overload the arity method and instead have &lt;strong&gt;numArgs?&lt;/strong&gt; which gets you the number of required arguments&amp;#8221;, &lt;strong&gt;hasOptional?&lt;/strong&gt; which gets you back a boolean as to whether there are optional arguments, and &lt;strong&gt;argsDefined?&lt;/strong&gt; which gets you back a boolean as to whether the Proc has defined arguments at all. Overloading the meaning of the return value just results in more code that needs to check for special cases and cases where you can&amp;#8217;t actually know which of two states is correct.&lt;/p&gt;

&lt;p&gt;Also, there seems to be confusion about my point in comparing it to Smalltalk&amp;#8217;s ifTrue:ifFalse:. Of course one should use Ruby idioms when doing Ruby. The ifTrue:ifFalse: example is just a simple and well understood example of having more than one block in your parameter list. I will say that there is a certain kind of semantic elegance that comes from having all your control flow done through methods and objects. Ruby advocates always say that in Ruby &amp;#8220;everything is an object&amp;#8221;, but it appears that blocks and control flow expressions are not, and in this regard Ruby doesn&amp;#8217;t quite live up to expectations set by Smalltalk and LISP.&lt;/p&gt;</description>
      <pubDate>Tue, 12 Sep 2006 10:59:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e8cc37dd-780e-455b-8d2c-be60d618505e</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2006/09/12/ruby-on-nails-scratching-a-chalkboard</link>
      <category>Programming</category>
      <category>ruby</category>
      <category>smalltalk</category>
      <category>blocks</category>
      <category>proc</category>
      <category>closures</category>
      <trackback:ping>http://xblog.xman.org/articles/trackback/20</trackback:ping>
    </item>
    <item>
      <title>Cincom Smalltalk + glibc-2.4 == hang</title>
      <description>&lt;p&gt;So, all this Ruby-ing has made me yearn for Smalltalk. Accordingly, I started trolling for Smalltalk implementations. Squeak is working well as always, but Cincom is available for free, so I thought I&amp;#8217;d give it a whirl. Just one catch: Cincom&amp;#8217;s VM appears to rely on Linuxthreads, and won&amp;#8217;t work on NPTL. This is a pitty as the latest glibc (2.4) no longer supports Linuxthreads.&lt;/p&gt;

&lt;p&gt;One more cheer for open source software!&lt;/p&gt;</description>
      <pubDate>Sun, 10 Sep 2006 22:22:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:35bbdab9-9fca-4408-8b25-9f016ca7ee1c</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2006/09/10/cincom-smalltalk-glibc-2-4-hang</link>
      <category>Programming</category>
      <category>smalltalk</category>
      <category>cincom</category>
      <category>linuxthreads</category>
      <category>glibc</category>
      <category>NPTL</category>
      <trackback:ping>http://xblog.xman.org/articles/trackback/14</trackback:ping>
    </item>
    <item>
      <title>My First Ruby Program</title>
      <description>&lt;p&gt;I realized that earlier today I wrote my first Ruby program, and it&amp;#8217;s probably worth documenting this moment for posterity.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a trivial bit of code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;Fixing Typo sequence numbers&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;postgres&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;sequences&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;blacklist_patterns&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;blogs&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;categories&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;contents&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;page_caches&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;pings&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;redirects&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;resources&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;sessions&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;sidebars&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;tags&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text_filters&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
  &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;triggers&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;]&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;fixSequence&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;tableName&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;results&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;query&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;select max(id) from &lt;span class="expr"&gt;#{tableName}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="ident"&gt;max_id&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;results&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;max_id&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt; 
    &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exec&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;select setval('&lt;span class="expr"&gt;#{tableName}&lt;/span&gt;_id_seq'::text,&lt;span class="expr"&gt;#{max_id}&lt;/span&gt;);&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;clear&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;db&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;PGconn&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;localhost&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="number"&gt;5432&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;sequences&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;sequence&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;fixSequence&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;sequence&lt;/span&gt;&lt;span class="punct"&gt;)}&lt;/span&gt;
&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;close&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So far, my first impression is that Ruby tries to be like Smalltalk, but is Perlish enough to fall short IMHO. Of course, I hardly know the language yet, so there may be a more elegant way to do things that I have yet to uncover. In particular, I&amp;#8217;m wondering why the True and False classes don&amp;#8217;t have &amp;#8220;ifTrue:ifFalse&amp;#8221; type methods that take blocks as arugments. Seems like an obvious &amp;#8220;nice to have&amp;#8221;. IIRC it&amp;#8217;s possible to add methods to existing classes, so maybe I can do this to keep the Smalltalk cravings to a minimum.&lt;/p&gt;</description>
      <pubDate>Sat, 09 Sep 2006 22:43:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:7db96642-3ab3-47f6-bc75-daf740928a7d</guid>
      <author>Christopher Smith</author>
      <link>http://xblog.xman.org/articles/2006/09/09/my-first-ruby-program</link>
      <category>Programming</category>
      <category>ruby</category>
      <category>typo</category>
      <category>postgres</category>
      <category>postgresql</category>
      <category>smalltalk</category>
      <category>sequences</category>
      <trackback:ping>http://xblog.xman.org/articles/trackback/12</trackback:ping>
    </item>
  </channel>
</rss>
