<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8341844892564516905</id><updated>2024-09-06T11:51:30.624-07:00</updated><category term="comment ruby"/><category term="ruby"/><category term="anonymous"/><category term="idiom"/><category term="metaclass"/><category term="no for statement"/><category term="pickaxe"/><category term="ruby block netbeans closure"/><category term="ruby if expression"/><category term="ruby io file close"/><category term="ruby jruby packaging package gem howto"/><category term="ruby modules mixins static dynamic"/><category term="ruby netbeans example prgramming"/><category term="ruby netbeans example programming"/><category term="ruby rdoc"/><category term="ruby russell brand"/><category term="ruby unit test pickaxe"/><category term="ruby unless expression"/><category term="singleton"/><category term="singleton ruby netbeans example programming"/><category term="tdd"/><category term="xunit"/><title type='text'>Ruby Eye for the Java Guy</title><subtitle type='html'>I&#39;m a Java programmer.  I&#39;m learning Ruby.  This is where I&#39;ll think out loud and collate my experiences.  Please tell me what you think.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-5643553232184742204</id><published>2008-09-13T01:45:00.001-07:00</published><updated>2008-09-13T01:49:55.251-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="tdd"/><category scheme="http://www.blogger.com/atom/ns#" term="xunit"/><title type='text'>xUnit in Ruby</title><content type='html'>I&#39;m working my way through Kent Beck&#39;s excellent &lt;a href=&quot;http://www.amazon.com/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530&quot;&gt;&quot;Test Driven Development: By Example&quot;&lt;/a&gt;.  Part 2 is all about using TDD to write an xUnit framwork.  The examples are in Python.  I decided to replicate them in Ruby for the practice:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYNoPvINW9CaYZu4jmITbiUBxXV6gDSJLCVprwc2JCVlkdpHwRKUIYrRp0WKxL1uECB9Hc0bQ4Mq8ElZqVqSgVcBFyAJ2sLJWbw2cHcJccnxLqI931mbW5VBliY7JPnEZVhvEmeQpWqvs/s1600-h/xUnit_in_Ruby1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYNoPvINW9CaYZu4jmITbiUBxXV6gDSJLCVprwc2JCVlkdpHwRKUIYrRp0WKxL1uECB9Hc0bQ4Mq8ElZqVqSgVcBFyAJ2sLJWbw2cHcJccnxLqI931mbW5VBliY7JPnEZVhvEmeQpWqvs/s320/xUnit_in_Ruby1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5245425048230540258&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;And the rest...&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBy8DxyIpx-rcThncwsUsuNad7uHRc3JM28HJ1Q8NBI4jlkgBqx5Kj9lCsMoJHBXFfLs_U1I0xiN76rcWQFlEXqcLLFnkkolN7zonffzwkZToGszd04lrq5od-KyIk3K9E0N8Ysox0Uw4/s1600-h/xUnit_in_Ruby2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBy8DxyIpx-rcThncwsUsuNad7uHRc3JM28HJ1Q8NBI4jlkgBqx5Kj9lCsMoJHBXFfLs_U1I0xiN76rcWQFlEXqcLLFnkkolN7zonffzwkZToGszd04lrq5od-KyIk3K9E0N8Ysox0Uw4/s320/xUnit_in_Ruby2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5245425297712435490&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/5643553232184742204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/5643553232184742204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/5643553232184742204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/5643553232184742204'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/09/xunit-in-ruby.html' title='xUnit in Ruby'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYNoPvINW9CaYZu4jmITbiUBxXV6gDSJLCVprwc2JCVlkdpHwRKUIYrRp0WKxL1uECB9Hc0bQ4Mq8ElZqVqSgVcBFyAJ2sLJWbw2cHcJccnxLqI931mbW5VBliY7JPnEZVhvEmeQpWqvs/s72-c/xUnit_in_Ruby1.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-3118610015048745154</id><published>2008-06-08T01:59:00.001-07:00</published><updated>2008-06-08T04:22:46.697-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="anonymous"/><category scheme="http://www.blogger.com/atom/ns#" term="idiom"/><category scheme="http://www.blogger.com/atom/ns#" term="metaclass"/><category scheme="http://www.blogger.com/atom/ns#" term="pickaxe"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="singleton"/><title type='text'>Ruby Idiom #1 and beyond: class &amp;lt;&amp;lt;self; self end</title><content type='html'>OK, so I&#39;ve worked my way through the &lt;a href=&quot;http://pragprog.com/titles/ruby3/programming-ruby-3&quot;&gt;Pickaxe Book&lt;/a&gt;.  Where now?  Time to read some real world code and see how Ruby gets used in the wild.  First idiom is one i&#39;ve read about before on &lt;a href=&quot;http://ola-bini.blogspot.com/&quot;&gt;Ola&#39;s blog&lt;/a&gt;, but didn&#39;t really &quot;get&quot;.  It appears right at the start of &lt;a href=&quot;http://code.whytheluckystiff.net/&quot;&gt;Why&lt;/a&gt;&#39;s &lt;a href=&quot;http://code.whytheluckystiff.net/camping&quot;&gt;Camping framework&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrZ4S6bpNxRb9m6_fz4qleIeOH-norXp94YPgrHNK9c7o0IhwkPy4UvMtAmSvQYoVXDLvuLFUFl71AHl52-zSbOx_HJcmBbb8SQbzTyV6MrhY9OftFWpmyTPYc9VuoVXsPWVI1fnxoJY/s1600-h/camping-1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrZ4S6bpNxRb9m6_fz4qleIeOH-norXp94YPgrHNK9c7o0IhwkPy4UvMtAmSvQYoVXDLvuLFUFl71AHl52-zSbOx_HJcmBbb8SQbzTyV6MrhY9OftFWpmyTPYc9VuoVXsPWVI1fnxoJY/s320/camping-1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209435863297172530&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;We&#39;ll ignore the surrounding class and method for the moment.  What does the semi cryptic &quot;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;span style=&quot;font-family:courier new;&quot;&gt;class &amp;lt;&amp;lt;self; self end&lt;/span&gt;&lt;/span&gt;&quot; bit do?  Well, Pickaxe will tell us that the &quot;class &amp;lt;&amp;lt;&lt;span style=&quot;font-style: italic;&quot;&gt;obj&lt;/span&gt;&quot; notation says &quot;build me a new class just for object &lt;span style=&quot;font-style: italic;&quot;&gt;obj&lt;/span&gt;&quot;.  This is called an &lt;span style=&quot;font-weight: bold;&quot;&gt;Anonymous or Singleton Class&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Lets rewind.  Firstly, remember that every object in Ruby has a class associated with it.  It&#39;s in the class where the object&#39;s methods are stored so it&#39;s pretty important - when you invoke a method on an object, Ruby looks for the object&#39;s class first and sees if it has the method it needs.&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifogD4BKI8_FKu38fAosC8FC9YJE3tZ1k9-BXCgitM0zHyCRj2dXEIGO6mvDlisEoMvbY7Sv_wL3DCt9ZLgLIjpHWqwTo-lkPy9uaQ2HQEwM2jUsLLLpj0R0kn5bCXX1AQk1bxy9DE5v8/s1600-h/diag-.PNG1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifogD4BKI8_FKu38fAosC8FC9YJE3tZ1k9-BXCgitM0zHyCRj2dXEIGO6mvDlisEoMvbY7Sv_wL3DCt9ZLgLIjpHWqwTo-lkPy9uaQ2HQEwM2jUsLLLpj0R0kn5bCXX1AQk1bxy9DE5v8/s320/diag-.PNG1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209463318146640610&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Got it?  Now a bit of additional complexity.  Classes are objects too.  This means that a class can have a class of its own.  This &lt;span style=&quot;font-style: italic;&quot;&gt;isn&#39;t&lt;/span&gt; it&#39;s Super Class.  Oh no, we&#39;ll get to them in a moment.  A classes class is a &lt;span style=&quot;font-weight: bold;&quot;&gt;Virtual Class&lt;/span&gt;, (indicated in the diagram below by the &#39;V&#39; flag)  and is the place where all the magic behind Ruby&#39;s open classes comes from.  If you add a new method &quot;blogMe&quot; to the class &quot;Movie&quot;, a new virtual class for the Movie class object is created and that&#39;s where your &quot;blogMe&quot; lives.  Pickaxe shows these virtual &lt;span style=&quot;font-weight: bold;&quot;&gt;Meta Classes &lt;/span&gt;as the classname with a &#39; appended to the name:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKZhlWeCsqBCZNsZSWfWWb5DJViBmr7oDmnXMCjTfuefa4Eb2htVVbEfuv1iIKxQLYZ9h8mkiB7JIyvDP1jK18ECEz5KMXGQn44R2hbYvHEgLGFrYYUFX56NhbwFiL8_3iyhl2E7E_oyQ/s1600-h/diag-2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKZhlWeCsqBCZNsZSWfWWb5DJViBmr7oDmnXMCjTfuefa4Eb2htVVbEfuv1iIKxQLYZ9h8mkiB7JIyvDP1jK18ECEz5KMXGQn44R2hbYvHEgLGFrYYUFX56NhbwFiL8_3iyhl2E7E_oyQ/s320/diag-2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209464569612976370&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Still with me?  Remember too that classes are &lt;span style=&quot;font-style: italic;&quot;&gt;special &lt;/span&gt;&lt;span&gt;objects&lt;/span&gt; - they also have &lt;span style=&quot;font-weight: bold;&quot;&gt;Super Classes&lt;/span&gt;.  This includes virtual classes (see how in the diagram above, they both have the &quot;super&quot; attribute).  This is how we get our class hierarchy.  If the Ruby interpreter is trying to invoke a method on an object and it doesn&#39;t find it on the object&#39;s class or virtual class, it&#39;ll look at the classes superclass to see what it has to offer.  Nae luck?  If the superclass has a super class, look there and just keep going...&lt;br /&gt;&lt;br /&gt;How do virtual classes methods fit into this hierarchy?  Remember a virtual class is a class of an object - the class.  It gets checked after a classes methods are checked, but before going up to a classes superclass.  Confused?  Hopefully not.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb8oApYEIrAgGAGX0g6Zj7xYGOQ1YaCv8zOyk-ZiUeq9i2ubOnpL41Oygn_F4eCXAPNnYf4gKnQjglaoqTc2B0zWL4j0rsDfp2hyphenhyphenUiHJzd8-u-Mrcd08Rav5fjv5f0bfAVXSpn-S2LZsI/s1600-h/diag-3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjb8oApYEIrAgGAGX0g6Zj7xYGOQ1YaCv8zOyk-ZiUeq9i2ubOnpL41Oygn_F4eCXAPNnYf4gKnQjglaoqTc2B0zWL4j0rsDfp2hyphenhyphenUiHJzd8-u-Mrcd08Rav5fjv5f0bfAVXSpn-S2LZsI/s320/diag-3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209466292594758018&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;So how do we bring &lt;span style=&quot;font-weight: bold;&quot;&gt;Singleton / Anonymous Classes&lt;/span&gt; into this?  Well, they&#39;re a &lt;span style=&quot;font-style: italic;&quot;&gt;new &lt;/span&gt;class, tied to a &lt;span style=&quot;font-style: italic;&quot;&gt;particular object &lt;/span&gt;and inserted between the object and it&#39;s real class.  Its referred to as a &quot;singleton&quot;because it is class-like, but exists only for the object which created it.  Its &quot;anonymous&quot; because it has no name. Indeed, the Pickaxe book uses the Singleton terminology and shows it in diagrams labeled &quot;virtual&quot; and with no name at all.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyoZjk6tQC7D19x0zCWE_xHYHmZ41AXXH4CemAcYK0NW_XbAfkPd-zwzgb2giCnDnHhHmsNDEoNViA4MBs8cyqXjN4jfUjOXaZ3cc0V5fNZh9MG2NZbHy4E1KxTVO7VJQL-ToxJX3hlHY/s1600-h/diag-4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyoZjk6tQC7D19x0zCWE_xHYHmZ41AXXH4CemAcYK0NW_XbAfkPd-zwzgb2giCnDnHhHmsNDEoNViA4MBs8cyqXjN4jfUjOXaZ3cc0V5fNZh9MG2NZbHy4E1KxTVO7VJQL-ToxJX3hlHY/s320/diag-4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209468860192354930&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;!!Potential Confusion Warning!!&lt;/span&gt;: Some folks wrongly refer to Singleton classes as &quot;&lt;span style=&quot;font-weight: bold;&quot;&gt;Meta Classes&lt;/span&gt;&quot;.  This confused folks so much that there is a special note in Pickaxe to help you out.  As they state, Ruby does have Meta Classes, but they are different from Smalltalk because Singletons are not a &lt;span style=&quot;font-style: italic;&quot;&gt;class of a class&lt;/span&gt;; they are a &lt;span style=&quot;font-style: italic;&quot;&gt;singleton&lt;/span&gt; class of a class&lt;br /&gt;&lt;br /&gt;So what can we do with all this?  Well, because we now have a class which exists solely for the object which created it, we can do things like addign methods to that object and that object alone.  This is what Why? is doing in the code clip:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrZ4S6bpNxRb9m6_fz4qleIeOH-norXp94YPgrHNK9c7o0IhwkPy4UvMtAmSvQYoVXDLvuLFUFl71AHl52-zSbOx_HJcmBbb8SQbzTyV6MrhY9OftFWpmyTPYc9VuoVXsPWVI1fnxoJY/s1600-h/camping-1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrZ4S6bpNxRb9m6_fz4qleIeOH-norXp94YPgrHNK9c7o0IhwkPy4UvMtAmSvQYoVXDLvuLFUFl71AHl52-zSbOx_HJcmBbb8SQbzTyV6MrhY9OftFWpmyTPYc9VuoVXsPWVI1fnxoJY/s320/camping-1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5209435863297172530&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;He&#39;s wrapped it up all nice for us in a method called &lt;span style=&quot;font-family:courier new;&quot;&gt;meta_def&lt;/span&gt;  (which is available to all objects which are of class Object - that&#39;s a lot).  It takes two parameters which are &#39;&lt;span style=&quot;font-family:courier new;&quot;&gt;m&lt;/span&gt;&#39;, the name for the new method, and &#39;&lt;span style=&quot;font-family:courier new;&quot;&gt;&amp;amp;b&lt;/span&gt; he creates a &#39;, the block which will be the body of the new method.  Once in the method, new Singleton class for the object which called the method, and then creates the method on the new singleton using the :define_method method and we&#39;re done.&lt;br /&gt;&lt;br /&gt;Short.  Sweet.  Elegant.&lt;br /&gt;&lt;br /&gt;I&#39;ve yet to see how Why? uses it.  I&#39;ll update this post when I get that far. ;-)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Further Reading:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://pragprog.com/titles/ruby3/programming-ruby-3&quot;&gt;The Pickaxe Book&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://ola-bini.blogspot.com/2006/09/ruby-singleton-class.html&quot;&gt;Ola Bini on The Ruby Singleton Class&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/3118610015048745154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/3118610015048745154' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/3118610015048745154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/3118610015048745154'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/06/ruby-idiom-1-and-beyond-class-self-end.html' title='Ruby Idiom #1 and beyond: class &amp;lt;&amp;lt;self; self end'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglrZ4S6bpNxRb9m6_fz4qleIeOH-norXp94YPgrHNK9c7o0IhwkPy4UvMtAmSvQYoVXDLvuLFUFl71AHl52-zSbOx_HJcmBbb8SQbzTyV6MrhY9OftFWpmyTPYc9VuoVXsPWVI1fnxoJY/s72-c/camping-1.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-4334288814233261418</id><published>2008-04-13T02:32:00.000-07:00</published><updated>2008-04-13T02:39:29.827-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby rdoc"/><title type='text'>Likin&#39; RDoc</title><content type='html'>I&#39;ve moved onto part 2 of Pickaxe.  Currently on the RDoc chapter.  I must say I&#39;m impressed how smiple it seems to keep things.  No fancy @param annotations to learn, just put a comment above your class /  attribute / method and you&#39;re off.  If you feel the need for more control of your formatting, you can get busy with a very wiki-like syntax.&lt;br /&gt;&lt;br /&gt;Its also interesting to note that if you click on a method, RDoc will show you the code.  It highlights a key difference between the Java and Ruby worlds.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/4334288814233261418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/4334288814233261418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4334288814233261418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4334288814233261418'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/04/likin-rdoc.html' title='Likin&#39; RDoc'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-1922538593538278363</id><published>2008-04-06T03:22:00.000-07:00</published><updated>2008-04-06T03:24:00.781-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby unit test pickaxe"/><title type='text'>Unit Testing in Ruby</title><content type='html'>Ruby comes with a Unit Test framework pre installed:  Nathaniel Talbott&#39;s Test::Unit.  The Pickaxe book devotes a whole chapter to it (and not at the back).  These are &lt;span style=&quot;font-style: italic;&quot;&gt;good things&lt;/span&gt;.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/1922538593538278363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/1922538593538278363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/1922538593538278363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/1922538593538278363'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/04/unit-testing-in-ruby.html' title='Unit Testing in Ruby'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-2929241366883464506</id><published>2008-04-05T01:22:00.000-07:00</published><updated>2008-04-05T02:03:13.902-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby io file close"/><title type='text'>Ruby I/O - Calling File.open with a block does the .close for me</title><content type='html'>More Ruby niceness.  This should look familiar to all Java guys and gals out there:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPtf2REW5m0Md-Gt1lgmAnnf2dwU8H1zDglNDD6K8LKfRPyWVvZirj4qX1xhJXQ73m9waTZH1Oh6KL0VAkrKg7WM60PcZB_7hI79aqm120-3-NWvUvlEVMfqt3HVdoR6iX_YmFq5LB8ng/s1600-h/chapter_10_blog_3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPtf2REW5m0Md-Gt1lgmAnnf2dwU8H1zDglNDD6K8LKfRPyWVvZirj4qX1xhJXQ73m9waTZH1Oh6KL0VAkrKg7WM60PcZB_7hI79aqm120-3-NWvUvlEVMfqt3HVdoR6iX_YmFq5LB8ng/s320/chapter_10_blog_3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5185676815733066626&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Repeat after me: &quot;Always be closing.  Always be closing.  Always be closing.&quot;&lt;br /&gt;&lt;br /&gt;But Ruby&#39;s File.open can also take a block to associate with the call:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeCq3tM3-rWcH9wCwkK8NJc6sU9eK5kPOVsZ3H6-sQZlUWVraR4s-XQqFh5M_Wy7qovlE0izdpfIR9RNfCKFb8F_RD7fXbDy78KGlMR29UYnbJlWq2Gqs7LN62ZaTdNXXxoHl_EVapOtk/s1600-h/chapter_10_blog_2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeCq3tM3-rWcH9wCwkK8NJc6sU9eK5kPOVsZ3H6-sQZlUWVraR4s-XQqFh5M_Wy7qovlE0izdpfIR9RNfCKFb8F_RD7fXbDy78KGlMR29UYnbJlWq2Gqs7LN62ZaTdNXXxoHl_EVapOtk/s320/chapter_10_blog_2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5185674874407848818&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;This invokes the block, passes the newly opened file to it as a parameter. When this is complete, the file is automatically closed for you.&lt;br /&gt;&lt;br /&gt;In addition to this, if an exception ocurs in the first example then the close will never be called until its GC&#39;d. (Bet you&#39;d miss checked exceptions then).  With the second example, the file is closed and then the exception is propogated to the caller.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/2929241366883464506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/2929241366883464506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2929241366883464506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2929241366883464506'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/04/ruby-io-fileopen-with-blocks-does.html' title='Ruby I/O - Calling File.open with a block does the .close for me'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPtf2REW5m0Md-Gt1lgmAnnf2dwU8H1zDglNDD6K8LKfRPyWVvZirj4qX1xhJXQ73m9waTZH1Oh6KL0VAkrKg7WM60PcZB_7hI79aqm120-3-NWvUvlEVMfqt3HVdoR6iX_YmFq5LB8ng/s72-c/chapter_10_blog_3.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-4772782183194337443</id><published>2008-03-31T10:06:00.000-07:00</published><updated>2008-03-31T10:19:57.324-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby modules mixins static dynamic"/><title type='text'>Lost a Safety Net</title><content type='html'>I&#39;ve just finished working through Chapter 9 of Pickaxe - Modules - and to be honest, it sacred me a little.  Now I&#39;m not religiously tied to static languages and can see the benefits something dynamic like Ruby can bring to me but there was something about Modules and name spaces which had me yearning for good &#39;ole Duke.&lt;br /&gt;&lt;br /&gt;Here&#39;s the scoop.  Mixins (using Modules as a way to provide multiple inheritance) allow you to provide instance variables.  If I create an @myString instance variable in my mixin, and then in my class which includes it I also have an instance variable with the same name it can all go horribly wrong.&lt;br /&gt;&lt;br /&gt;But here&#39;s the pain.  In nice statically checked land, the compiler (best chum o&#39; mine) will flag my goof.  In Ruby-land, there is no compiler.  Things might even work for a while.  Worse still they miht break without my knowing it.  Then finding the problem would be pretty nasty and debug-steppy.&lt;br /&gt;&lt;br /&gt;Now I know I should have created a nice set of unit tests to avoid this, but in a complex application I can see things like this falling between the cracks;  horrible nasty cracks with spikes and stuff at the bottom.  Yurgh! &lt;br /&gt;&lt;br /&gt;Or am I just being over sensitive?&lt;br /&gt;&lt;br /&gt;Before I close, there are a few other confusions this deceptively short chapter threw up:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I thought everything in Ruby was a class.  Even objects.  How come then Pickaxe states &quot;a module isn&#39;t a class&quot; (page 119).  Hmmm.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;include / require / load / aaaaarhg&lt;/span&gt;&lt;/span&gt;!  I like Java&#39;s &quot;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;import&lt;/span&gt;&lt;/span&gt;&quot; better and despite the problems, classpaths sheild the rest from me in 90% of situations (though heaven forbid when I have to debug a classloader problem, or worst still, implement one of my own...)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/4772782183194337443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/4772782183194337443' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4772782183194337443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4772782183194337443'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/03/lost-safety-net.html' title='Lost a Safety Net'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-2835172186908988720</id><published>2008-01-05T09:42:00.000-08:00</published><updated>2008-01-05T09:46:59.409-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="comment ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="no for statement"/><title type='text'>Ruby Has No &quot;for&quot; Loop - Woo Hoo!</title><content type='html'>I held onto my hat when I heard this one.  I use the &#39;for&#39; loop in Java &lt;span style=&quot;font-style: italic;&quot;&gt;a lot&lt;/span&gt;.  Probably more than I ought.  &#39;How will this work&#39; I thought?  No &#39;for&#39; loop?  Nonsense ...&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLO_ieRJk1Akouwd4g6E1sMJMZBXZfNEkzHAhjZvuGJOh9uEVYwyxVR1CEc_8UPha2XJOdBAKvp_OiizH8DwgW3pUMUj1byomZEq01e9jkM-345QPTOlcqJHP9Ll-JLEQ_Xn3y2lwklOo/s1600-h/ruby3.bmp&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLO_ieRJk1Akouwd4g6E1sMJMZBXZfNEkzHAhjZvuGJOh9uEVYwyxVR1CEc_8UPha2XJOdBAKvp_OiizH8DwgW3pUMUj1byomZEq01e9jkM-345QPTOlcqJHP9Ll-JLEQ_Xn3y2lwklOo/s320/ruby3.bmp&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5152049853512079602&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;When I saw it I liked it.  Its often said (by me too &lt;a href=&quot;http://rubyeyeforthejavaguy.blogspot.com/2008/01/ruby-if-expressions-terse-and-legible.html&quot;&gt;earlier&lt;/a&gt;) that one of the reasons Ruby is so great is that it &lt;span style=&quot;font-style: italic;&quot;&gt;reads&lt;/span&gt;.  Well, here&#39;s another example of just that.  I like.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/2835172186908988720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/2835172186908988720' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2835172186908988720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2835172186908988720'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/01/ruby-has-no-for-loop-woo-hoo.html' title='Ruby Has No &quot;for&quot; Loop - Woo Hoo!'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLO_ieRJk1Akouwd4g6E1sMJMZBXZfNEkzHAhjZvuGJOh9uEVYwyxVR1CEc_8UPha2XJOdBAKvp_OiizH8DwgW3pUMUj1byomZEq01e9jkM-345QPTOlcqJHP9Ll-JLEQ_Xn3y2lwklOo/s72-c/ruby3.bmp" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-8785979009908388669</id><published>2008-01-05T09:28:00.001-08:00</published><updated>2008-01-05T09:28:48.782-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby unless expression"/><title type='text'>Glorious Negated &quot;if&quot; - &quot;unless&quot;</title><content type='html'>It continues!  More and more comfort and joy ... Behold:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS3KHjYyfBSwW-Q-ExJnXGQsLJ9IIwadsEEYxoBzEHBd-KW7n4V1WMcKXhN-taGSlgd0SQJAjB8-qkZkQ1FcLvYCLwfPmtGEXUJ_gq37nM-YsSifIZ2Kg5zC8zurYiGOBw5lxsJ0mc9j5L/s1600-h/ruby2.bmp&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS3KHjYyfBSwW-Q-ExJnXGQsLJ9IIwadsEEYxoBzEHBd-KW7n4V1WMcKXhN-taGSlgd0SQJAjB8-qkZkQ1FcLvYCLwfPmtGEXUJ_gq37nM-YsSifIZ2Kg5zC8zurYiGOBw5lxsJ0mc9j5L/s320/ruby2.bmp&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5152042139750815970&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Ahhhh!  A warm hug from my code.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/8785979009908388669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/8785979009908388669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8785979009908388669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8785979009908388669'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/01/glorious-negated-if-unless.html' title='Glorious Negated &quot;if&quot; - &quot;unless&quot;'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS3KHjYyfBSwW-Q-ExJnXGQsLJ9IIwadsEEYxoBzEHBd-KW7n4V1WMcKXhN-taGSlgd0SQJAjB8-qkZkQ1FcLvYCLwfPmtGEXUJ_gq37nM-YsSifIZ2Kg5zC8zurYiGOBw5lxsJ0mc9j5L/s72-c/ruby2.bmp" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-2356666641885680195</id><published>2008-01-05T09:04:00.000-08:00</published><updated>2008-01-05T09:07:50.651-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby if expression"/><title type='text'>Ruby If Expressions- Terse and Legible</title><content type='html'>More Ruby Pickaxe Learning.  &quot;if&quot; expressions today (not &quot;if&quot; &lt;span style=&quot;font-style: italic;&quot;&gt;statements&lt;/span&gt; either - they return values don&#39;t you know).  I was pleased to see just how terse and legible they can be:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvgMCPMuXoAuTe192r5F_jOmS8BQloaEUbJpDuWoJRZmPdBE9imwxbFRBOIz7JDkZaKj4AiHQpTTFLd7RgQXOh9L65WV5y6O3QkUbzcL3UJm7R0-pmnbZ3tPPS10Ibbv9kIzkL3O9OXOk/s1600-h/ruby.bmp&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvgMCPMuXoAuTe192r5F_jOmS8BQloaEUbJpDuWoJRZmPdBE9imwxbFRBOIz7JDkZaKj4AiHQpTTFLd7RgQXOh9L65WV5y6O3QkUbzcL3UJm7R0-pmnbZ3tPPS10Ibbv9kIzkL3O9OXOk/s320/ruby.bmp&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5152040039511808210&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Beautiful.</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/2356666641885680195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/2356666641885680195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2356666641885680195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/2356666641885680195'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2008/01/ruby-if-expressions-terse-and-legible.html' title='Ruby If Expressions- Terse and Legible'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvgMCPMuXoAuTe192r5F_jOmS8BQloaEUbJpDuWoJRZmPdBE9imwxbFRBOIz7JDkZaKj4AiHQpTTFLd7RgQXOh9L65WV5y6O3QkUbzcL3UJm7R0-pmnbZ3tPPS10Ibbv9kIzkL3O9OXOk/s72-c/ruby.bmp" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-4530182235701473555</id><published>2007-09-18T03:56:00.000-07:00</published><updated>2007-09-18T04:02:14.944-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby russell brand"/><title type='text'>Boy do I Love Ruby...</title><content type='html'>This fact about Ruby isn&#39;t a surprise, I just needed to express how much I    love that fact that all numbers are objects: &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTlnRUlGIV1hvsxganc2pZxBj2UkUnat81sxOglL8zpIk_6GJSM7VZfOqiFbzQr__Uioz9CveNvNCvQxLRASrJsI7Xue8FoxY6l9fmsX00kCQVq_HSiJ73qTFTXh77T3rioAMQzJc8bmQ/s1600-h/ruby-love-1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTlnRUlGIV1hvsxganc2pZxBj2UkUnat81sxOglL8zpIk_6GJSM7VZfOqiFbzQr__Uioz9CveNvNCvQxLRASrJsI7Xue8FoxY6l9fmsX00kCQVq_HSiJ73qTFTXh77T3rioAMQzJc8bmQ/s320/ruby-love-1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111497100307531330&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Come to me sweet DSL&#39;s! Massage me expressive and terse code constructs! Relieve    my angst and pain and potential RSI!&lt;/p&gt; &lt;p&gt;(Sorry. To much &lt;a href=&quot;http://www.bbc.co.uk/radio2/shows/brand/&quot;&gt;Russell Brand&lt;/a&gt; on the plane this morning...)&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/4530182235701473555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/4530182235701473555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4530182235701473555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4530182235701473555'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/09/boy-do-i-love-ruby.html' title='Boy do I Love Ruby...'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTlnRUlGIV1hvsxganc2pZxBj2UkUnat81sxOglL8zpIk_6GJSM7VZfOqiFbzQr__Uioz9CveNvNCvQxLRASrJsI7Xue8FoxY6l9fmsX00kCQVq_HSiJ73qTFTXh77T3rioAMQzJc8bmQ/s72-c/ruby-love-1.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-4584973831248506873</id><published>2007-09-18T03:41:00.000-07:00</published><updated>2007-09-18T03:48:03.449-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby block netbeans closure"/><title type='text'>Even More Ruby Surprises - Blocks and Closures 101</title><content type='html'>For me, the Ruby learning continues apace. This weekend it was the turn of blocks and    closures, however first I&#39;d like to mention a little pecadillo which made me    smile.  &lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise C1 - Parallel Assignment&lt;/p&gt; &lt;p&gt;Now those Ruby folks constantly bang on about how expressive Ruby is and generally    then go off into very complicated and convoluted discussions as to why, but    this, to me is a perfect illustration:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuxMqSHMUAHVMOYmns4iUWWsWAP6tI-2AAlpywcMN1B8Zkum_OyyJKONUm_pSl28YAcCvZ2ZI1WLXXvRar0Pd9nIlzzHXk28VaezrMkDVum0cFXy3JAef8CGumxGMWrTyAGiAMULb1lrQ/s1600-h/ruby-surprises-1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuxMqSHMUAHVMOYmns4iUWWsWAP6tI-2AAlpywcMN1B8Zkum_OyyJKONUm_pSl28YAcCvZ2ZI1WLXXvRar0Pd9nIlzzHXk28VaezrMkDVum0cFXy3JAef8CGumxGMWrTyAGiAMULb1lrQ/s320/ruby-surprises-1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493647153825250&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;What this says to me is &quot;I have some variables. I want to call them this    and this, and I want them to equal this and this.&quot; Simple and legible.    Nice&lt;/p&gt; &lt;p&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Surprise C2 - Blocks Can Have (Multiple) Parameters Passed to Them and Can    Return Values Too&lt;/span&gt; &lt;/p&gt; &lt;p&gt;Now coming from a Java background, the whole concept of blocks and closures    was a bit of a mystery to me. (Now I do get anonymous inner classes, but frankly    the whole &lt;a href=&quot;http://the-music-of-time.blogspot.com/2007/05/javaone-2007-closures-for-java-language.html&quot;&gt;Closures debate &lt;/a&gt;had me a little confused.)    No longer. After a single paragraph in the &lt;a href=&quot;http://www.pragmaticprogrammer.com/titles/ruby/index.html&quot;&gt;PickAxe&lt;/a&gt; (which I won&#39;t restate    here, suffice to say you should buy the book) I now see what they&#39;re all about    and how damn useful they can be. I can also see how useful passing a parameter    to a block can be:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEJedCP6yCLN95FJaXgV-LteWk8hg23o0PXXEO3uhi2_HVaNaOzPl4UHf1Dal0ewqa6ChyCtLfF6qPVUZ1RxkoyEmPmTpgiRVq-ed9UKU8Mj44T2s5j5HwBya8xq9m6OGjlUxruahB6Xw/s1600-h/ruby-surprises-2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEJedCP6yCLN95FJaXgV-LteWk8hg23o0PXXEO3uhi2_HVaNaOzPl4UHf1Dal0ewqa6ChyCtLfF6qPVUZ1RxkoyEmPmTpgiRVq-ed9UKU8Mj44T2s5j5HwBya8xq9m6OGjlUxruahB6Xw/s320/ruby-surprises-2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493647153825266&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And if we combine this with the ability to return a value from a block too:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh47t9MjAZyjg76E2x-ykxrJbpTPZ6g4UAMOg4WauE-csr3s57fpkLDGPmtoGV6ioyn1YfojyDKEhBMgKEXdf9-Ak83Gzn_ofGUpOuGul_tal1t7ufke3CfJakqotmoVFggE5OiFOoZDQk/s1600-h/ruby-surprises-3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh47t9MjAZyjg76E2x-ykxrJbpTPZ6g4UAMOg4WauE-csr3s57fpkLDGPmtoGV6ioyn1YfojyDKEhBMgKEXdf9-Ak83Gzn_ofGUpOuGul_tal1t7ufke3CfJakqotmoVFggE5OiFOoZDQk/s320/ruby-surprises-3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493651448792578&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And how about multiple paramaters? Easy:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYQkal6lGMh-CxPWb9xpksrbS9juhBDlKbgcQUMSwF74RVo449sKPGWzGsZWpVCgFHzEuzy-TrlCgYPByWoZofLMI4hbtHC4r8cYORU1DNNXGTPoopNiU66amLZeMyR4Yget31L0vK7X4/s1600-h/ruby-surprises-4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYQkal6lGMh-CxPWb9xpksrbS9juhBDlKbgcQUMSwF74RVo449sKPGWzGsZWpVCgFHzEuzy-TrlCgYPByWoZofLMI4hbtHC4r8cYORU1DNNXGTPoopNiU66amLZeMyR4Yget31L0vK7X4/s320/ruby-surprises-4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493977866307090&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;All in all, blocks seem really controllable and intuitive (to me at least).&lt;/p&gt; &lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise C3 - Ruby Functions Can React According to Whether They Were Called    With a Block or Not&lt;/p&gt; &lt;p&gt;It gets even better. Ruby also allows you to simply code functions which can    be called with blocks as well as without. If you call with a block, they can    react in their own special way:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv_B_tLhng_Gh4tAo5foViA502fXgAxTpUYddSUfZkTgwQqZ3j_FY5LSSfMwCUwKQUGGU0vB9OYv2gKmJ3_7R0IrwU62IH6bsjuftcKAcJ-TbvODnHI2UeqIbLGvHN9xTS7wguhVtvdf4/s1600-h/ruby-surprises-5.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv_B_tLhng_Gh4tAo5foViA502fXgAxTpUYddSUfZkTgwQqZ3j_FY5LSSfMwCUwKQUGGU0vB9OYv2gKmJ3_7R0IrwU62IH6bsjuftcKAcJ-TbvODnHI2UeqIbLGvHN9xTS7wguhVtvdf4/s320/ruby-surprises-5.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493982161274402&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise C4 - Ruby Blocks Can Be Closures&lt;/p&gt; &lt;p&gt;What we&#39;ve seen so far haven&#39;t strictly speaking been closures. However, Ruby    does allow you to use blocks in such a way that they are - blocks can be passed    as arguments, and then assigned to variables as Proc objects, and then exceuted    using the Proc#call method. To seal the deal, Ruby makes sure that it remembers    the context in which a block was &lt;em&gt;defined.&lt;/em&gt; That is to say the value    of &quot;self&quot;, plus the methods, variables and constants in scope. Behold:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzdocRYvTbpVIjCPLTcSOehZunZAgHKY-GYYefUUfspMku06NMGI3sJOeAlkHqre7gvPqASvWhxrIHbUFLnC8iLgJDp2b2c_egIMR2Fvo8FJaiZdJYk4CzNmXWnFvTJXVjkOxW5Utnvto/s1600-h/ruby-surprises-6.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzdocRYvTbpVIjCPLTcSOehZunZAgHKY-GYYefUUfspMku06NMGI3sJOeAlkHqre7gvPqASvWhxrIHbUFLnC8iLgJDp2b2c_egIMR2Fvo8FJaiZdJYk4CzNmXWnFvTJXVjkOxW5Utnvto/s320/ruby-surprises-6.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5111493982161274418&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Netbeans 6 Note: The grey squiggles under the start_button and pause_button    variables indicates that they have been initialised, but not yet used. Handy    eh?&lt;/p&gt; &lt;p&gt;Hasta luego!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/4584973831248506873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/4584973831248506873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4584973831248506873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4584973831248506873'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/09/even-more-ruby-surprises-blocks-and.html' title='Even More Ruby Surprises - Blocks and Closures 101'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuxMqSHMUAHVMOYmns4iUWWsWAP6tI-2AAlpywcMN1B8Zkum_OyyJKONUm_pSl28YAcCvZ2ZI1WLXXvRar0Pd9nIlzzHXk28VaezrMkDVum0cFXy3JAef8CGumxGMWrTyAGiAMULb1lrQ/s72-c/ruby-surprises-1.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-3175818767088436948</id><published>2007-09-14T05:12:00.000-07:00</published><updated>2007-09-14T05:28:00.947-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby netbeans example programming"/><title type='text'>More Ruby Surprises (and my first Ruby Disappointment)</title><content type='html'>I&#39;m still going at the &lt;a href=&quot;http://www.rubycentral.com/pickaxe/&quot;&gt;PickAxe book&lt;/a&gt;. This time it&#39;s arrays... &lt;p style=&quot;font-weight: bold;&quot;&gt;Ruby Surprise B1 - You can use negative indexes&lt;/p&gt; &lt;p&gt;If I use a negative index as the index to your array, it works, but you count    from the right hand end, rather than the left:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBo66OSk8WAuLKLk4KN8_jvxs-4QsbnbqkkPQRdYiVPo4bhncleDto0OkxtotBDBszYOf38niaHlD4w7CvUAn9U69A8Hxtb26FECxhnZsqWH6Kx4TtZYUGWNwB9fQn8P1Kh9Anvq3Q5fQ/s1600-h/ruby-surprises-1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBo66OSk8WAuLKLk4KN8_jvxs-4QsbnbqkkPQRdYiVPo4bhncleDto0OkxtotBDBszYOf38niaHlD4w7CvUAn9U69A8Hxtb26FECxhnZsqWH6Kx4TtZYUGWNwB9fQn8P1Kh9Anvq3Q5fQ/s320/ruby-surprises-1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032327481034098&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Ruby Surprise B2 - No ArrayIndexOutOfBoundsException&lt;/p&gt; &lt;p&gt;If I blow the bounds on my array, I just get a nil, rather than an ArrayIndexOutOfBoundsException    equivalent:&lt;/p&gt; &lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFtKgNC1exxCygTb3TChA_FxewcZagc0LxoHiXSK2hc0hEgi-IcRz67m8fdZlNMjfJLK7NGJnR3F8e2-GU-SoR9cNYILJ1eb10R9-67xMqoaW0SN9KKB89HuT5zOFXC52lz81r9ahvuIo/s1600-h/ruby-surprises-2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFtKgNC1exxCygTb3TChA_FxewcZagc0LxoHiXSK2hc0hEgi-IcRz67m8fdZlNMjfJLK7NGJnR3F8e2-GU-SoR9cNYILJ1eb10R9-67xMqoaW0SN9KKB89HuT5zOFXC52lz81r9ahvuIo/s320/ruby-surprises-2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032331776001410&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;p style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Ruby Surprise B3 - Addressing Ranges is Easy&lt;/p&gt; &lt;p&gt;There are a number of ways to get a range of values from my array. The first    is to pass in two arguments, the start index and the range size:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZiS3C08M4tA1FHV6a5xF5LquXFrm16YmKEb4iadFot41U5CEC0ipcK3al8i3ucY7o21erC0ZLDiDvcsj6rJ7gt0TipxL9TMescyNcPZhCWPPpKkucoHvcrQ9Ml7MoUQLeNIP9jBIEcE/s1600-h/ruby-surprises-3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZiS3C08M4tA1FHV6a5xF5LquXFrm16YmKEb4iadFot41U5CEC0ipcK3al8i3ucY7o21erC0ZLDiDvcsj6rJ7gt0TipxL9TMescyNcPZhCWPPpKkucoHvcrQ9Ml7MoUQLeNIP9jBIEcE/s320/ruby-surprises-3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032331776001426&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;Then there is the start index and the end index version...:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhg7EbJ9BaTWk5UvdtpfdOgvDl1aHPvDKFagTf_7epHob8SUyeRubcP8cXeZxL_XJq6bupymr7YRDTTlefelWxH8MIODa3Kl0_OL5cyAhXDSs2XzM6pOtakXbQPyUguw2rdKial_NW0Kc/s1600-h/ruby-surprises-4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhg7EbJ9BaTWk5UvdtpfdOgvDl1aHPvDKFagTf_7epHob8SUyeRubcP8cXeZxL_XJq6bupymr7YRDTTlefelWxH8MIODa3Kl0_OL5cyAhXDSs2XzM6pOtakXbQPyUguw2rdKial_NW0Kc/s320/ruby-surprises-4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032769862665634&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;Or the start index and the one before the end index version...:&lt;/p&gt; &lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSE83naKTEuFHc5hkMgRf23sjsTZT9K-0-MsaUgS73tF_fa_4SY2sMtOoc1ptcEaIpocIwAraoXVQ7Hoe4wdLMSiTP559JXz220hixeZ5wCsNq8BdwlRuZpRS762J77WABXomewx3yJNM/s1600-h/ruby-surprises-5.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSE83naKTEuFHc5hkMgRf23sjsTZT9K-0-MsaUgS73tF_fa_4SY2sMtOoc1ptcEaIpocIwAraoXVQ7Hoe4wdLMSiTP559JXz220hixeZ5wCsNq8BdwlRuZpRS762J77WABXomewx3yJNM/s320/ruby-surprises-5.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032769862665650&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;p&gt;&lt;br /&gt;And I can even use the negative indexing paradigm as mentioned in Surprise    B1...:&lt;/p&gt; &lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDX_BXYkwADkmce5JLcQgXVfMf-U6gqXi6x95XA9a2nkjoqpwdVSEEMRmYoKOVM_mq6WkuMRCE-mEUOYb_rEPOk_I3p-tDlqqQDDObGnU-3JULViAucjRp5Q7PzJ7vMofK5XWgoKgNNMs/s1600-h/ruby-surprises-6.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDX_BXYkwADkmce5JLcQgXVfMf-U6gqXi6x95XA9a2nkjoqpwdVSEEMRmYoKOVM_mq6WkuMRCE-mEUOYb_rEPOk_I3p-tDlqqQDDObGnU-3JULViAucjRp5Q7PzJ7vMofK5XWgoKgNNMs/s320/ruby-surprises-6.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110032769862665666&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Ruby Dissapointment 1 - You can&#39;t Count Backwards Through an Array (but Groovy    can)&lt;/p&gt;&lt;p style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;This works in Groovy (which I am learning from a colleague has a very similar syntax to Ruby) but not Ruby:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhROyDyNnIN51J7Y55-aIHXB62kTWzCN57fZrUSzFrrYAReKO8NW3ykfBZFOXCTuUhjZLSUP1K1veVW5zlz6Ld_wMA8l_rvgER0D3_dIo9ZG82NtIRXH7pNDoKrAM-Dzx_42P-EDTIgRPY/s1600-h/ruby-surprises-7.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhROyDyNnIN51J7Y55-aIHXB62kTWzCN57fZrUSzFrrYAReKO8NW3ykfBZFOXCTuUhjZLSUP1K1veVW5zlz6Ld_wMA8l_rvgER0D3_dIo9ZG82NtIRXH7pNDoKrAM-Dzx_42P-EDTIgRPY/s320/ruby-surprises-7.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5110035093439972818&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/3175818767088436948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/3175818767088436948' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/3175818767088436948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/3175818767088436948'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/09/more-ruby-surprises-and-my-first-ruby.html' title='More Ruby Surprises (and my first Ruby Disappointment)'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBo66OSk8WAuLKLk4KN8_jvxs-4QsbnbqkkPQRdYiVPo4bhncleDto0OkxtotBDBszYOf38niaHlD4w7CvUAn9U69A8Hxtb26FECxhnZsqWH6Kx4TtZYUGWNwB9fQn8P1Kh9Anvq3Q5fQ/s72-c/ruby-surprises-1.PNG" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-8737845853806097902</id><published>2007-09-08T08:34:00.001-07:00</published><updated>2007-09-08T08:52:52.722-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby netbeans example prgramming"/><title type='text'>Ruby Surprises - Back to the Beginning with the PickAxe</title><content type='html'>I&#39;ve recently bought &lt;a href=&quot;http://www.pragmaticprogrammer.com/titles/ruby/index.html&quot;&gt;the famous PickAxe book&lt;/a&gt;. The plan? To go back over all I know about Ruby from a different perspective to make sure I understand all the subtleties of the language. Here are some of the surprises so far for me, someone coming from Java land.&lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise 1 - Classes are Always Open&lt;/p&gt;In Ruby, classes are always open. This means that when you want to add a new method to them, you simply open them (with a new &quot;class ... end&quot;) and add the code you require:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpQaKYWMzoQZpwf1aPy75ZuGGiN5kQvhZerjwIxcyU6nJdY5q4JQlkbclckfRmi9MRH5hAlxAKNFLZMBxmZv6qNWAc2VNwh2sDm5n4pMdor7oFGGplI9aXIKZx6coSrECCQt_NXpBWsS0/s1600-h/ruby-surprises1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpQaKYWMzoQZpwf1aPy75ZuGGiN5kQvhZerjwIxcyU6nJdY5q4JQlkbclckfRmi9MRH5hAlxAKNFLZMBxmZv6qNWAc2VNwh2sDm5n4pMdor7oFGGplI9aXIKZx6coSrECCQt_NXpBWsS0/s320/ruby-surprises1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860162096466002&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;Here we&#39;ve defined a new class &quot;Song&quot; and given it an initializer. Later (just below in fact) we&#39;ve realised we need to add a &quot;to_s&quot; method. This is simple to do, simply by re opening the definition of Song. Ruby now sees the Song class as being a combination of all that we&#39;ve defined for it. Therefore, when we run our code we get the following result:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEire4wdKgQWxG-EOU1v6CGjplIuZYgxszezNXA2OB3XL_aciU4UB5vIScAVhskVLhvYnM6FRUpAYI3QIeHFnnKiXgRCa8wwdhXbv9k75r0l-1DLofJN0hqFTsU-IXBU8oDcJydM_YGoJ1M/s1600-h/ruby-surprises1-output.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEire4wdKgQWxG-EOU1v6CGjplIuZYgxszezNXA2OB3XL_aciU4UB5vIScAVhskVLhvYnM6FRUpAYI3QIeHFnnKiXgRCa8wwdhXbv9k75r0l-1DLofJN0hqFTsU-IXBU8oDcJydM_YGoJ1M/s320/ruby-surprises1-output.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860162096466018&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;NOTE: You can redefine any class you want, not just ones you&#39;ve created yourself.  This scares some hardcore Java programmers.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise 2 - To Redefine a Subclass, No Need to Restate the Extension&lt;/p&gt;Here we&#39;re going to do exactly the same as before with the &quot;Song&quot; example, but now we&#39;ll use a Subclass of Song; &quot;KaraokeSong&quot;. As you&#39;d expect, the first time we define KaraokeSong, we need to tell Ruby that it extends Song. However, when we re define it to add a &quot;to_s&quot; method, we can treat it simply as the class that it is. Ruby already knows it extends Song:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsB7Sr1Z7qpUAjU_TjhDx6RtVWj_V6IkbJLC0258ChIQX1NjAeN4NqravtHR67UFlDGf1O32ql5XTTmMuKmboZuhdwpERm6wBQN_2042IXVZYUM0CO560_oXrdeTlURRfSNttz_7YknWY/s1600-h/ruby-surprises2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsB7Sr1Z7qpUAjU_TjhDx6RtVWj_V6IkbJLC0258ChIQX1NjAeN4NqravtHR67UFlDGf1O32ql5XTTmMuKmboZuhdwpERm6wBQN_2042IXVZYUM0CO560_oXrdeTlURRfSNttz_7YknWY/s320/ruby-surprises2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860166391433330&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;(Netbeans) Surprise 3 - Netbeans can&#39;t do Code Completion on Already Defined Variables in a Class Re-Definition&lt;/span&gt;&lt;br /&gt;&lt;p&gt;I guess this is probably too much to ask, but as I&#39;m trying to learn how to use the &lt;a href=&quot;http://wiki.netbeans.info/wiki/view/Ruby&quot;&gt;Netbeans Ruby Editor&lt;/a&gt; at the same time as I learn Ruby, it is worth nothing that code completion for variables doesn&#39;t work if you are in a piece of code which is re defining a class which contains them:&lt;/p&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitjPcA6bqa3pMidlBVCynrkL-jfh5OYZLIupFRmDYET9gSWAzD4Y5yfmyn6d4cNdHPQTTsXGzuoSbxDu_OQAlSkVZKJ3m7Tkuqc6SwXv7aCQcHPC3-I-y6HshKp9ytxGUURH0U4h0H2zA/s1600-h/ruby-surprises3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitjPcA6bqa3pMidlBVCynrkL-jfh5OYZLIupFRmDYET9gSWAzD4Y5yfmyn6d4cNdHPQTTsXGzuoSbxDu_OQAlSkVZKJ3m7Tkuqc6SwXv7aCQcHPC3-I-y6HshKp9ytxGUURH0U4h0H2zA/s320/ruby-surprises3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860960960383106&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;On the positive side, it is &lt;em&gt;very&lt;/em&gt; cool that code completion works within String literals. Regex completion is a godsend too.&lt;br /&gt;&lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise 4 - Slimline Ruby Encapsulation&lt;/p&gt;Anyone who has nearly gone insane hand-coding Javabean encapsulation code without the refactoring help of an IDE will have railed against the verbosity of the getXxxx and setXxxx paradigm. I was pleasantly surprised therefore to discover the simplicity and expressivity of the Ruby encapsulation code:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLVseqEKXuMzTJqLS5jXZTz1XPLCZ50D_Hu1Z0tRdPsy8ZJDw-2ofHYSEgtTmAJjqLyAqVy0emkDOG1BwLZVYnHl-CNdCZw8PQZ12h5KiCGY_blXQ8hTSw6LnGWj0QkFqZQ0aDqXmyik4/s1600-h/ruby-surprises4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLVseqEKXuMzTJqLS5jXZTz1XPLCZ50D_Hu1Z0tRdPsy8ZJDw-2ofHYSEgtTmAJjqLyAqVy0emkDOG1BwLZVYnHl-CNdCZw8PQZ12h5KiCGY_blXQ8hTSw6LnGWj0QkFqZQ0aDqXmyik4/s320/ruby-surprises4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860965255350418&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;This to me makes it look as if the attribute is not encapsulated (which makes client code simpler and easier to read) when in fact it is (which means you get all the good points of encapsulation). Cool.&lt;br /&gt;&lt;p style=&quot;font-weight: bold;&quot;&gt;Surprise 5 - You can Encapsulate &lt;em&gt;Virtual&lt;/em&gt; Attributes&lt;/p&gt;Using this Ruby encapsulation idiom, you can encapsulate &lt;em&gt;virtual&lt;/em&gt; attributes (i.e. ones which do not exist as actual instance variables):&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgggUQelEI5GKtbPQ6EGCtE6oIwAuAB8wxCgXpDxybVX6SfNsf9VQAE7-n4WyKuxlFzQkPr-JBsxN_0srE3i5gYOvYgDWQRMvaZVx4V0bK1cn3C7D3v6RjkfVZWlU4b1QMQutZc12nILsc/s1600-h/ruby-surprises5.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgggUQelEI5GKtbPQ6EGCtE6oIwAuAB8wxCgXpDxybVX6SfNsf9VQAE7-n4WyKuxlFzQkPr-JBsxN_0srE3i5gYOvYgDWQRMvaZVx4V0bK1cn3C7D3v6RjkfVZWlU4b1QMQutZc12nILsc/s320/ruby-surprises5.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860965255350434&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;(Netbeans) Surprise 6 - Class Attributes Must be Initialised Before You Use Them &lt;/span&gt;&lt;br /&gt;&lt;p&gt;It&#39;s a rule that a Ruby class attribute must be initialised before you use it. Netbeans reinforces this by not providing it as an option in code completion if you forget to do so (Though it would be cool if there was an associated tool tip to remind you to follow the rules):&lt;/p&gt;&lt;p&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEOeswpPYmbE-t2_mrvQC-T5-qfNQETBEpA8vofiaiUhyphenhyphenHJ0-C8BBpXFGivWljQzzZp7Jg2bNc1wySWRGpGEh17_EUVlW3HoGloNvKdi2RlJZCyEXp2nXqIuCt6Pt2kUbUXm9HAtdfJIg/s1600-h/ruby-surprises6.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEOeswpPYmbE-t2_mrvQC-T5-qfNQETBEpA8vofiaiUhyphenhyphenHJ0-C8BBpXFGivWljQzzZp7Jg2bNc1wySWRGpGEh17_EUVlW3HoGloNvKdi2RlJZCyEXp2nXqIuCt6Pt2kUbUXm9HAtdfJIg/s320/ruby-surprises6.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5107860969550317746&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;That&#39;s it for now.  More to follow as I progress through the book...&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/8737845853806097902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/8737845853806097902' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8737845853806097902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8737845853806097902'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/09/ruby-surprises-back-to-beginning-with.html' title='Ruby Surprises - Back to the Beginning with the PickAxe'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpQaKYWMzoQZpwf1aPy75ZuGGiN5kQvhZerjwIxcyU6nJdY5q4JQlkbclckfRmi9MRH5hAlxAKNFLZMBxmZv6qNWAc2VNwh2sDm5n4pMdor7oFGGplI9aXIKZx6coSrECCQt_NXpBWsS0/s72-c/ruby-surprises1.PNG" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-8235393211490858182</id><published>2007-04-30T01:58:00.001-07:00</published><updated>2007-04-30T02:27:20.601-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby jruby packaging package gem howto"/><title type='text'>Packaging a Simple JRuby App Plus Gems</title><content type='html'>I&#39;ve pretty much finished &lt;a href=&quot;http://the-music-of-time.blogspot.com/2007/03/project-acta-diurna-harnessing-rss.html&quot;&gt;my first real ruby application&lt;/a&gt;. It&#39;s dead simple but does make use of two gems - &lt;a href=&quot;http://code.whytheluckystiff.net/hpricot/&quot;&gt;Hpricot&lt;/a&gt; and &lt;a href=&quot;http://simple-rss.rubyforge.org/&quot;&gt;simple-rss&lt;/a&gt;. Now, as I&#39;ve blogged before the plan is to make this deployable as simply as possible to any system with a JVM available.&lt;br /&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;The big question I still had was how to package it? I was aware there had been some ruby magic going on while I wrote it what with the gems and everything but I did know that if I got a hold of the complete JRuby distribution available as a single jar file (the eponymous &lt;a href=&quot;http://repo1.maven.org/maven2/org/jruby/jruby-complete/0.9.9/&quot;&gt;jruby-complete.jar&lt;/a&gt; which turned out to be a little hard to track down) I would be able to then just poke things into life with a simple &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;java&lt;/span&gt;&quot; command:&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;font-family:courier new;&quot;&gt;java-jar jruby-complete-0.9.9.jar main.rb&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;I tried this and it worked perfectly. Until we hit one or my &#39;&lt;span style=&quot;font-family:courier new;&quot;&gt;require&lt;/span&gt;&#39; calls to the gems I&#39;d used.  How to get round that? I had a look around as usual. Ruby being ruby, the vast majority of information is on blogs, newsgroups and wikis.  Unfortunately for me the &lt;a href=&quot;http://www.headius.com/jrubywiki/index.php/Main_Page&quot;&gt;JRuby wiki&lt;/a&gt; was down and all the blog entries were talking about far more complicated stuff to do with Rails. I was on my own...&lt;br /&gt;&lt;br /&gt;So I had a look at the gems which I had installed.  It&#39;s simple to find them (once you know where to look) just go to your ruby installation&#39;s home directory (CRuby or JRuby it&#39;s all the same) and then &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;.\lib\ruby\gems\1.8\gems&lt;/span&gt;&quot;.  There you can see a list of all the gems your installation of ruby knows about:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7igBjYiCTooNE14wXx3_t7FybTkFcrYnK7SrnvDyNuU4ViMuVzX2Ow7PQtCLIXPQr60RjgVopzRdKqlZnvJZrGld_GymFAec0VKcMH6JI4hTtkhr0D-qnyDglHxnDyMU4zaOG6w-DaU/s1600-h/blog2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7igBjYiCTooNE14wXx3_t7FybTkFcrYnK7SrnvDyNuU4ViMuVzX2Ow7PQtCLIXPQr60RjgVopzRdKqlZnvJZrGld_GymFAec0VKcMH6JI4hTtkhr0D-qnyDglHxnDyMU4zaOG6w-DaU/s320/blog2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5059148541518946738&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;You can see they are just directories.  I had a look inside the aptly named &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;simple-rss&lt;/span&gt;&quot; to see if what it contained made sense:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2Iy3VnCIpfF7EIK6UUkDDincJY3bgXXWx6hwg8NVTYbqejG_vUQ0L29kBbXQC2ZbXmpL0Z5I396vWKFpO2ulOONIC3MTqnbuBpPO_3c2nf148TLCq2m7xANm0kHGxuqRIyAD210TBiLc/s1600-h/blog3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2Iy3VnCIpfF7EIK6UUkDDincJY3bgXXWx6hwg8NVTYbqejG_vUQ0L29kBbXQC2ZbXmpL0Z5I396vWKFpO2ulOONIC3MTqnbuBpPO_3c2nf148TLCq2m7xANm0kHGxuqRIyAD210TBiLc/s320/blog3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5059148756267311554&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Seems simple enough.  I read the &lt;span style=&quot;font-family:courier new;&quot;&gt;README&lt;/span&gt; but it didn&#39;t tell me what I needed to know but the &lt;span style=&quot;font-family:courier new;&quot;&gt;lib &lt;/span&gt;directory looked promising:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc0YlFB4AymT57YPj2sdCxCkgkjSAj4IJaTXnxb1im2TZ_iUgNsiJoeaZ-rFXYXGKEQosNdleyQI6I5-GHelmPPONbGhsgQjlGU4PDpKGec87Fgsf_vdJUFdE3LIFbzVyueZmMf8CFqdM/s1600-h/blog4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc0YlFB4AymT57YPj2sdCxCkgkjSAj4IJaTXnxb1im2TZ_iUgNsiJoeaZ-rFXYXGKEQosNdleyQI6I5-GHelmPPONbGhsgQjlGU4PDpKGec87Fgsf_vdJUFdE3LIFbzVyueZmMf8CFqdM/s320/blog4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5059148958130774482&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Only a single &lt;span style=&quot;font-family:courier new;&quot;&gt;.rb&lt;/span&gt; file, excellent.  I coped this to my project&#39;s &lt;span style=&quot;font-family:courier new;&quot;&gt;lib&lt;/span&gt; directory (where all my &lt;span style=&quot;font-family:courier new;&quot;&gt;.rb &lt;/span&gt;files live and ran the &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;java&lt;/span&gt;&quot; command again.  I was making progress, now the &#39;&lt;span style=&quot;font-family:courier new;&quot;&gt;require&lt;/span&gt;&#39; complaint was related to Hpricot.&lt;br /&gt;&lt;br /&gt;Hpricot is a little more complicated.  The standard version uses some components written in C.  If you choose to download it manually from &lt;a href=&quot;http://code.whytheluckystiff.net/&quot;&gt;_why&#39;s subversion repo&lt;/a&gt; this is the one you will get.&lt;br /&gt;&lt;br /&gt;NOTE: You can get most ruby libraries directly in this way without having to use ruby gems.  &lt;a href=&quot;http://rubyforge.org/&quot;&gt;Ruby Forge&lt;/a&gt; allows you to download them manually and if you open the archives you will find they have the same structure as when you use &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;gem -install&lt;/span&gt;&quot; to get them.&lt;br /&gt;&lt;br /&gt;Luckily, there is also a jruby version of hpricot for jrubyists which you can get via &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;gem -install&lt;/span&gt;&quot;.  I looked in my jruby &lt;span style=&quot;font-family:courier new;&quot;&gt;gems&lt;/span&gt; directory again and found the Hpricot gem:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7izVGBk22dUYEPQI9VslkUo5mZubzz9cBAui3AjOCgEdVczv7UHzMXYot86Z3khtW8vEohAIQCOaf9I7FLwhkWHhjhlTsDMKbwMpnwSsJ5OT5GzeCCIAXjf-OAi5wsrRk-g3UOlw1ks/s1600-h/blog5.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7izVGBk22dUYEPQI9VslkUo5mZubzz9cBAui3AjOCgEdVczv7UHzMXYot86Z3khtW8vEohAIQCOaf9I7FLwhkWHhjhlTsDMKbwMpnwSsJ5OT5GzeCCIAXjf-OAi5wsrRk-g3UOlw1ks/s320/blog5.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5059149649620509154&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;A little more complicated this time but now I knew where I was going -&lt;span style=&quot;font-family:courier new;&quot;&gt;./lib&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjTesDpt8Dfrj6UZ7Xyfngj9E6cNGEt68LvzPOQ57SvesLHNArxdxPvTRqRocYaU43gCuO-kxwIcJOkVF6-_Adf860S0XOma0vL6M9dMUTaGdUFOKZ4tlZvlhyLDhsZhBOJ1JTeWq0K1I/s1600-h/blog6.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjTesDpt8Dfrj6UZ7Xyfngj9E6cNGEt68LvzPOQ57SvesLHNArxdxPvTRqRocYaU43gCuO-kxwIcJOkVF6-_Adf860S0XOma0vL6M9dMUTaGdUFOKZ4tlZvlhyLDhsZhBOJ1JTeWq0K1I/s320/blog6.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5059149894433645042&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;More than a single file this time but still pretty simple.  I made an assumption that I could just do as I had before and just copy the complete contents of this folder across to my app.  I did, ran the &quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;java&lt;/span&gt;&quot; command again and it worked.  &quot;&lt;a href=&quot;http://www.imdb.com/title/tt0080745/&quot;&gt;Gordon&#39;s Alive!&lt;/a&gt;&quot;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Loose Ends...&lt;/span&gt;&lt;br /&gt;1. There are a few loose ends to tie up.  I mentioned that the default Hpricot uses some C elements.  These can be seen if you download the library manually and look in the &lt;span style=&quot;font-family: courier new;&quot;&gt;./lib&lt;/span&gt; directory.  There, instead of &quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;hpricot_scan.jar&lt;/span&gt;&quot; you&#39;ll see &quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;hpricot_scan.so&lt;/span&gt;&quot;.  Not good for java...&lt;br /&gt;&lt;br /&gt;2. It seems to me that if the jruby guys can package all the jruby bits and pieces inside a single jar, I could use the same method to package my bits and pieces with theirs and make my app a single jar file too.  I&#39;ll blog about it when I figure out how to do this.  In the meantime, I&#39;m happy with a directory containing my ruby files, some html, the jruby jar and some shell scripts to keep me away from the command line.&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/8235393211490858182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/8235393211490858182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8235393211490858182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/8235393211490858182'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/04/packaging-simple-jruby-app-plus-gems.html' title='Packaging a Simple JRuby App Plus Gems'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp7igBjYiCTooNE14wXx3_t7FybTkFcrYnK7SrnvDyNuU4ViMuVzX2Ow7PQtCLIXPQr60RjgVopzRdKqlZnvJZrGld_GymFAec0VKcMH6JI4hTtkhr0D-qnyDglHxnDyMU4zaOG6w-DaU/s72-c/blog2.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-514706250654471469</id><published>2007-04-29T07:14:00.000-07:00</published><updated>2007-04-29T07:21:06.000-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="comment ruby"/><title type='text'>Ruby Convention - Return Value Comments on Statements</title><content type='html'>It is a Ruby convention to provide comments on the return value of a statement.  E.g.:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjox7UOPa2aa0WauNLt7qgRtXzabA0m4YP3hCURjWDHWtXkyuTSBFegCbVwb_eKq0K-hZTmuNnrABgnvb8siV5EVqjF72wgsAzYM0U0TdUJNs5D1n-A7gP7DydlVI7v1EFlb6PcaCj-1FY/s1600-h/blog1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjox7UOPa2aa0WauNLt7qgRtXzabA0m4YP3hCURjWDHWtXkyuTSBFegCbVwb_eKq0K-hZTmuNnrABgnvb8siV5EVqjF72wgsAzYM0U0TdUJNs5D1n-A7gP7DydlVI7v1EFlb6PcaCj-1FY/s320/blog1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058854916079755666&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;With code colouring this is quite clear but can otherwise be confusing to a learner already confused with the unfamiliar syntax (like me)</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/514706250654471469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/514706250654471469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/514706250654471469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/514706250654471469'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/04/ruby-convention-return-value-comments.html' title='Ruby Convention - Return Value Comments on Statements'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjox7UOPa2aa0WauNLt7qgRtXzabA0m4YP3hCURjWDHWtXkyuTSBFegCbVwb_eKq0K-hZTmuNnrABgnvb8siV5EVqjF72wgsAzYM0U0TdUJNs5D1n-A7gP7DydlVI7v1EFlb6PcaCj-1FY/s72-c/blog1.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8341844892564516905.post-4337225323335872183</id><published>2007-04-29T06:41:00.001-07:00</published><updated>2007-04-29T07:11:57.873-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="singleton ruby netbeans example programming"/><title type='text'>Singleton Classes in Ruby</title><content type='html'>After &lt;a href=&quot;http://the-music-of-time.blogspot.com/2007/04/instance-variables-initialization-and.html&quot;&gt;my last post&lt;/a&gt; on &lt;a href=&quot;http://the-music-of-time.blogspot.com/&quot;&gt;my other blog&lt;/a&gt; where I&#39;d described trying to get my head around Ruby inheritance and instance variables I got this comment:&lt;br /&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbB5_PO0rMD823HhGC-zXpIrbdsNCsrOsPWvgNbCf0NaWMEX8oL0x0FY-92-DULCf59utAiRDddiHIyZ-iSf5DnskjGkd28cdhnI0Q2zrWTEmkJ2s1KhO5z13cgY3lxrLcOoD3UvScXMQ/s1600-h/blog1.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbB5_PO0rMD823HhGC-zXpIrbdsNCsrOsPWvgNbCf0NaWMEX8oL0x0FY-92-DULCf59utAiRDddiHIyZ-iSf5DnskjGkd28cdhnI0Q2zrWTEmkJ2s1KhO5z13cgY3lxrLcOoD3UvScXMQ/s320/blog1.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058845574525886658&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;To start with it confused me. (The &#39;&lt;span style=&quot;font-family:courier new;&quot;&gt;#&lt;/span&gt;&#39; on the last line was missing too which didn&#39;t help.) As I&#39;m still a real noob when it comes to Ruby I still have trouble coming to terms with the compact syntax which others use; however I&#39;m in this to learn so I had a fiddle and here is the fruit of my labours.&lt;br /&gt;&lt;br /&gt;It turns out (after a fair bit of &lt;i&gt;&lt;a href=&quot;http://www.google.com/&quot;&gt;googling&lt;/a&gt;/&lt;a href=&quot;http://www.yahoo.com/&quot;&gt;yahooing&lt;/a&gt;&lt;/i&gt; - spread the love man) that this is an example of a Ruby Singleton Class.  I&#39;ll explain below but should first note that this is very much lifted from &lt;a href=&quot;http://ola-bini.blogspot.com/2006/09/ruby-singleton-class.html&quot;&gt;Ola Bini&#39;s post on the topic&lt;/a&gt;.  I take it slower with some more code and hopefully some Java angles.  Just to be clear, this is not original work but represents my thought processes in understanding Ola&#39;s illustration.&lt;br /&gt;&lt;br /&gt;Ready?  Lets go.&lt;br /&gt;&lt;br /&gt;1. Ruby has no concept of things being final; unlike in Java.   If I want to add a method or attribute to the String class, I just do it (you can even do this to Java classes when using JRuby, but let&#39;s not complicate things):&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlDtix63zb-f3cPt5N7uwZUtT7FSp_x5J1MyBIRCiS-kU5pkrRF99VNdwtEqfmIt75lu1C_Cthvb6i-E-IwoW36vYcY-Qr_tOIrlZ9nc81aWsgU4hahhznAROjvDg96xvcHDb3Z9wuiN8/s1600-h/blog2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlDtix63zb-f3cPt5N7uwZUtT7FSp_x5J1MyBIRCiS-kU5pkrRF99VNdwtEqfmIt75lu1C_Cthvb6i-E-IwoW36vYcY-Qr_tOIrlZ9nc81aWsgU4hahhznAROjvDg96xvcHDb3Z9wuiN8/s320/blog2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058846137166602450&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Note: You can see that Netbeans had seen that I&#39;ve added a method to my &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; class and offers it as an option in the code completion dialogue.  I&#39;ll continue to use the info Netbeans gives me as it maps onto how I think about Java.&lt;br /&gt;&lt;br /&gt;When I run it I get this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRgdQRk1piLchc4dWonQjWGAa_sd1zZ05MWbjLeJXyGXh0RVQ4JdzL7aQ2e-CVvMW1_PruqwHf0jsx7Pc472ue8xGpwWu6jS-rkOsmd58GZpHH3qBGxn-FaFVn1V8H7siz6sfjsimzOwc/s1600-h/blog3.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRgdQRk1piLchc4dWonQjWGAa_sd1zZ05MWbjLeJXyGXh0RVQ4JdzL7aQ2e-CVvMW1_PruqwHf0jsx7Pc472ue8xGpwWu6jS-rkOsmd58GZpHH3qBGxn-FaFVn1V8H7siz6sfjsimzOwc/s320/blog3.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058847103534244066&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Cool.  I&#39;ve added a new method to the &lt;span style=&quot;font-family:courier new;&quot;&gt;String &lt;/span&gt;class (a &quot;Class Method&quot; no less) and it&#39;s available from all my &lt;i&gt;instances&lt;/i&gt; of the &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; class from now on.  Ruby sees this as a good thing because you, the developer are free to place code where it makes sense to you and your object model - i.e. if I want my &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; to be able to say &quot;hello&quot; then this should go on the &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; class) But this isn&#39;t what we need to think about; more of a dipping of our toe in the water. Lets move on...&lt;br /&gt;&lt;br /&gt;2. In Ruby, &lt;i&gt;everything&lt;/i&gt; is an object, and all objects have a &lt;i&gt;class&lt;/i&gt; which they are an &lt;i&gt;instance&lt;/i&gt; of.  You can get at these classes by calling the method &lt;span style=&quot;font-family:courier new;&quot;&gt;class&lt;/span&gt; on any object you like.  When you start coding the methods of your class will only be the ones available by defaut to that object&#39;s class. We can see these in Netbeans if we press CTRL-SPACE to get code completion:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2kvAI2Sx74EfEkXQEIM82-9IIRi-QsEaE3MOprU_Ny4ms5xDIwlhhqcpQpPuW2m42q8WrGhKRKw9NPQGSYM35bkQPgEtBT7imxStN59HfduJeDOvTW5nnTwQ7OI9WrxFlaY9Nff8Ks0g/s1600-h/blog3b.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2kvAI2Sx74EfEkXQEIM82-9IIRi-QsEaE3MOprU_Ny4ms5xDIwlhhqcpQpPuW2m42q8WrGhKRKw9NPQGSYM35bkQPgEtBT7imxStN59HfduJeDOvTW5nnTwQ7OI9WrxFlaY9Nff8Ks0g/s320/blog3b.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058847541620908274&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Then we just saw we can add to this list by redefining the class itself in the standard way.  There is however another way.  Ruby also allows you to add new methods to any &lt;i&gt;object&lt;/i&gt;.  How?  This is the first (and more intuitive to Java folks) way:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA7N6NWhX2-5LX_rB9fHgDMjWu5cn9FmYMQYyjVXKZ1gsFCspJNl7mtr2fK4gUITznkYR3TcM6oy_05erq7qHm2ecGKYNvu5TALe99ylObjjSg9mhEig6U3QulwDtvKENIMF_QS5Teq2o/s1600-h/blog4a.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA7N6NWhX2-5LX_rB9fHgDMjWu5cn9FmYMQYyjVXKZ1gsFCspJNl7mtr2fK4gUITznkYR3TcM6oy_05erq7qHm2ecGKYNvu5TALe99ylObjjSg9mhEig6U3QulwDtvKENIMF_QS5Teq2o/s320/blog4a.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058847820793782530&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Which gives us this when we run it:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpyMBExMYiXMgU6MckyFThhfx-TjDSyTHk_gGWq1aEnIDDVA2Xnk0lJ5FffYD2UhvlpPi366fT5dHtddHTtx5cC64mqyodsEijbWhift-YABDpXogqInBxTR2zREZL8lKEaSQkJ_vBzEg/s1600-h/blog4b.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpyMBExMYiXMgU6MckyFThhfx-TjDSyTHk_gGWq1aEnIDDVA2Xnk0lJ5FffYD2UhvlpPi366fT5dHtddHTtx5cC64mqyodsEijbWhift-YABDpXogqInBxTR2zREZL8lKEaSQkJ_vBzEg/s320/blog4b.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058848018362278162&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Super.  As I&#39;d expect.  But there is another way and now we are heading into the land of Singleton classes.  We can get an object&#39;s class by using &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;class&lt;/span&gt;&quot;.  We can use &quot;&amp;lt;&amp;lt;&quot; to push this onto the class definition extension which follows.  E.g.:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq3wzl8j5QSRGhLgjfOJMjts2Mj4KOswtlmsVqTpvz_K-SX1IPAsftlQKbTXtEec0ztjFtiu7Tt5_vJ0pWaMLvEsYBcHihXqU5xNKlzx17Hz4MX5KBTXRWanIQlApgOz8eteKXmcC3EWI/s1600-h/blog4.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq3wzl8j5QSRGhLgjfOJMjts2Mj4KOswtlmsVqTpvz_K-SX1IPAsftlQKbTXtEec0ztjFtiu7Tt5_vJ0pWaMLvEsYBcHihXqU5xNKlzx17Hz4MX5KBTXRWanIQlApgOz8eteKXmcC3EWI/s320/blog4.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058848593887895842&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Again we can see that in the line of test code, Nebeans has picked this up and offers &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;bar&lt;/span&gt;&quot; as an optional method on our &lt;span style=&quot;font-family:courier new;&quot;&gt;foo&lt;/span&gt; object. We won&#39;t run it as I&#39;m sure you can guess what it does.  We have added a method to a &lt;span style=&quot;font-family:courier new;&quot;&gt;foo&lt;/span&gt; object.&lt;br /&gt;&lt;br /&gt;All still aboard? Lets complicate things further. We&#39;ve added a method to &lt;span style=&quot;font-family:courier new;&quot;&gt;foo&lt;/span&gt; which is a n instance of &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt;.  Is this method available to other &lt;span style=&quot;font-family:courier new;&quot;&gt;Strings&lt;/span&gt;?  Code completion will tell us:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDYjAEpEOn1vncse9vn3cnvwEUhWwGxnJP2bFUb0swC8_uafrDVPBOm428S7qKWo2gjKsW_MUFvIg17OV9uPaKwN7V34zaJlag44DkpUovKVnKNEoJZmW9cp07CXKJ5OI-Vr3yx5G_c4E/s1600-h/blog4c.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDYjAEpEOn1vncse9vn3cnvwEUhWwGxnJP2bFUb0swC8_uafrDVPBOm428S7qKWo2gjKsW_MUFvIg17OV9uPaKwN7V34zaJlag44DkpUovKVnKNEoJZmW9cp07CXKJ5OI-Vr3yx5G_c4E/s320/blog4c.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058849040564494642&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Hmmm.  Not on the list.  If we look at the Navigator pane it&#39;s telling us the same thing:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiUtcOJJ1UXo3PsRfMGxkWC0b38jdrPI8-g_fXnXTXYHJSuWy3cFjMk6mpXq9qWTzl11jlg8cfite7xVYNZ6kk16TRRzfPhcPVymnBWC0g35-Jgl4OHfNHB1Uc9a1aW1j1V7WsZ-WdC3I/s1600-h/blog4d.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiUtcOJJ1UXo3PsRfMGxkWC0b38jdrPI8-g_fXnXTXYHJSuWy3cFjMk6mpXq9qWTzl11jlg8cfite7xVYNZ6kk16TRRzfPhcPVymnBWC0g35-Jgl4OHfNHB1Uc9a1aW1j1V7WsZ-WdC3I/s320/blog4d.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058849259607826754&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;And there&#39;s the clue; &lt;span style=&quot;font-family:courier new;&quot;&gt;foo&lt;/span&gt; is now listed as a &lt;i&gt;class&lt;/i&gt; with our &lt;span style=&quot;font-family:courier new;&quot;&gt;bar&lt;/span&gt; method defined on it.  What? Remember we said everything in Ruby is an object?  Well, it turns out that even &lt;i&gt;classes &lt;/i&gt;are objects. Confused?  Free yourself from your Java chains!  It means we can frig around with them just like anything else we can get our grubby mits on but we need to be aware of what Ruby does for us when we do.&lt;br /&gt;&lt;br /&gt;What is happening is that when we define a new method on a specific object an new, anonymous class is inserted between that object and the real class (in this case &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt;&quot;) which defines it. (Remember, Ruby only has single inheritance so this is pretty easy to picture in your head.)  When we call a method on &lt;span style=&quot;font-family:courier new;&quot;&gt;foo&lt;/span&gt;, the interpreter first looks inside the anonymous class for a definition (if there is one) and then on to the real class.&lt;br /&gt;&lt;br /&gt;Now for the final push.  You&#39;ll have probably guessed that our anonymous class is actually what is called a &lt;i&gt;Singleton class&lt;/i&gt;.  Seems fair, but why the &quot;Singleton&quot;?  As we&#39;ve seen, all objects can have a Singleton class, even if the original user didn&#39;t intend it.  You want it, you can add it.  Fine.  Now know that &lt;i&gt;classes are objects themselves&lt;/i&gt;.  Following me?  I&#39;ll say it slowly as it took me a while too;  C-l-a-s-s-e-s a-r-e o-b-j-e-c-t-s.&lt;br /&gt;&lt;br /&gt;Lets take an example, the &lt;i&gt;class&lt;/i&gt; &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; is actually an &lt;i&gt;instance&lt;/i&gt; of the class &lt;span style=&quot;font-family:courier new;&quot;&gt;Class,&lt;/span&gt;as are all classes. There is nothing special about these instances.  Their names are capitalised simply because they are constants. Now, because every class is an instance of &lt;span style=&quot;font-family:courier new;&quot;&gt;Class&lt;/span&gt;, what are called Class Methods in Ruby or Static Methods in Java are actually just a special case of Singleton Methods; ones which are defined on the instance of the class in question.  Lets add a Singleton Method to the &lt;span style=&quot;font-family:courier new;&quot;&gt;String&lt;/span&gt; class.  As I&#39;m coming to learn with Ruby, there&#39;s more than one way to do it, but there is a preferred way.  First, the &lt;i&gt;non preferred&lt;/i&gt; way:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiicDJyJefdRerJNdXTLLlGzZ4vJGPK_FRdZdUvZ2TMkKhZgbY5N2lSK1Anb4SwXwhSecrmuEg7IForIWiBoSIXIUg87QrWaXkREPEUY7H5f5OlM1URU3LCEZRqn_4CKg52QsfHJ2rRfKU/s1600-h/blog5.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiicDJyJefdRerJNdXTLLlGzZ4vJGPK_FRdZdUvZ2TMkKhZgbY5N2lSK1Anb4SwXwhSecrmuEg7IForIWiBoSIXIUg87QrWaXkREPEUY7H5f5OlM1URU3LCEZRqn_4CKg52QsfHJ2rRfKU/s320/blog5.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058850316169781586&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;And now the preferred way:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjguNNMPBpcwftOMI8035Q_t5FTnk8FSs57WhsK78zkPPmNnNha-JIFYfy5lzsRdq48UIg9tQaAnJS2LaR42_Vi3yuXuBSQEjrenhdeGEWCxPn5Fwue2E8NyqMLu84KgPXZzd1WxJFs_ro/s1600-h/blog5a.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjguNNMPBpcwftOMI8035Q_t5FTnk8FSs57WhsK78zkPPmNnNha-JIFYfy5lzsRdq48UIg9tQaAnJS2LaR42_Vi3yuXuBSQEjrenhdeGEWCxPn5Fwue2E8NyqMLu84KgPXZzd1WxJFs_ro/s320/blog5a.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058850509443309922&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;The first way is pretty simple.  It&#39;s dead like the first example, &lt;i&gt;way&lt;/i&gt; up the top of this page but the new &lt;span style=&quot;font-family:courier new;&quot;&gt;hello&lt;/span&gt; method is private (It turns out that &quot;private&quot; in Ruby isn&#39;t what &quot;private&quot; is in Java but that&#39;s another post...) ; a &lt;i&gt;Singleton Method&lt;/i&gt;.  So why is the second way preferred? It&#39;s because it makes explicit the Singleton Class, both to you the developer and also to Ruby.&lt;br /&gt;&lt;br /&gt;First, you the developer: In Ruby you need to think about how the code reads to you as a human being, not as a compiler as Java has taught you.  This way shows us that the Singleton class is defined &lt;i&gt;inside&lt;/i&gt; the class definition, and hello is defined on &lt;i&gt;it&lt;/i&gt;.  Just read it and you&#39;ll see.&lt;br /&gt;&lt;br /&gt;Second, Ruby:  Look at the Navigator for this way and compare it with the navigator for the first way.  There is an extra &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;self&lt;/span&gt;&quot; class in between the String and our function.  This is the embodyment of the Singleton class.&lt;br /&gt;&lt;br /&gt;We should explain this &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;self&lt;/span&gt;&quot; a little more.  Used on it&#39;s own in our code, &quot;&lt;span style=&quot;font-family:courier new;&quot;&gt;self&lt;/span&gt;&quot; lets us get access to the class instance we are using it on like the first class in the code below.  When used in a similar way to the preferred way it now gets us the Singleton class instance.  We can see this in the second class.  Again, look at the Navigator pane where it is made clear:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gHBcuU5uxoF0qJvYrfjQr84KX6aKf1Osa0FHP7xlQ9rMZ9QGlSKJzf9bZn0b_ELwE8v5AkjIvdrWiOd5J8P4Al9OtiT4QIfFDbiMLAP3_mHbMkE-oXJhkaMghTuk-hZLVzkpRsDAFa8/s1600-h/blogA2.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gHBcuU5uxoF0qJvYrfjQr84KX6aKf1Osa0FHP7xlQ9rMZ9QGlSKJzf9bZn0b_ELwE8v5AkjIvdrWiOd5J8P4Al9OtiT4QIfFDbiMLAP3_mHbMkE-oXJhkaMghTuk-hZLVzkpRsDAFa8/s320/blogA2.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058851162278338930&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;We can see that the syntax to get access to the Singleton class is the same we used to get access to &lt;span style=&quot;font-family:courier new;&quot;&gt;foo.bar&lt;/span&gt;.  We also can see that the navigator shows the clear difference between the two String classes - the latter has a Singleton class.&lt;br /&gt;&lt;br /&gt;What about the differences between what these methods return? The former (the so called &quot;regular self&quot;) returns the class instance: &quot;String&quot;.  The latter returns the Singleton class for the String.&lt;class:string&gt;&lt;br /&gt;&lt;br /&gt;So finally, lets return to the comment which started all this in the first place:&lt;br /&gt;&lt;br /&gt;&lt;/class:string&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7x82_e4bdRoo7ZmcJoeowp1fw847zPCpVaIBJETtkolWqIQqC0c6_vtAFm1GzYM7G811ljiHtOcN96zcvvyYEwevvChbNe9Pr9K7tg9XRHzHIWjp9xOJZJp-Blf4zKBtw7_4BIgnBO2A/s1600-h/blog11.PNG&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7x82_e4bdRoo7ZmcJoeowp1fw847zPCpVaIBJETtkolWqIQqC0c6_vtAFm1GzYM7G811ljiHtOcN96zcvvyYEwevvChbNe9Pr9K7tg9XRHzHIWjp9xOJZJp-Blf4zKBtw7_4BIgnBO2A/s320/blog11.PNG&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5058851686264349058&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;class:string&gt;Clearly, we are defining a class (&quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;C&lt;/span&gt;&quot;) and then adding a Singleton method and what I can only assume is called a Singleton attribute called &quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;method&lt;/span&gt;&quot;.  We then create a sub class of this (&quot;&lt;span style=&quot;font-family: courier new;&quot;&gt;D&lt;/span&gt;&quot;) and the last line of the code demonstrates that this sub class has access to the Singleton class instance.  If we look at the Navigator, we can see all this laid out nicely for us as a hierarchy.&lt;br /&gt;&lt;br /&gt;So why is this important?  Well, as the comment stated, this is a nice and simple way to inherit class instance variables but more importantly this idiom is used in meta-programming, a mainstay or the Ruby world.  For more detail on this I&#39;d better leave it to &lt;a href=&quot;http://ola-bini.blogspot.com/2006/09/ruby-singleton-class.html&quot;&gt;Ola and his blog&lt;/a&gt;.&lt;/class:string&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rubyeyeforthejavaguy.blogspot.com/feeds/4337225323335872183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8341844892564516905/4337225323335872183' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4337225323335872183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8341844892564516905/posts/default/4337225323335872183'/><link rel='alternate' type='text/html' href='http://rubyeyeforthejavaguy.blogspot.com/2007/04/singleton-classes-in-ruby.html' title='Singleton Classes in Ruby'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbB5_PO0rMD823HhGC-zXpIrbdsNCsrOsPWvgNbCf0NaWMEX8oL0x0FY-92-DULCf59utAiRDddiHIyZ-iSf5DnskjGkd28cdhnI0Q2zrWTEmkJ2s1KhO5z13cgY3lxrLcOoD3UvScXMQ/s72-c/blog1.PNG" height="72" width="72"/><thr:total>3</thr:total></entry></feed>