<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>occasionally useful &#187; ruby</title>
	<atom:link href="http://blog.maxaller.name/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.maxaller.name</link>
	<description>ruby, ubuntu, etc</description>
	<lastBuildDate>Sun, 11 Jul 2010 07:01:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Grandparent of Ruby and Java: Eiffel and friends</title>
		<link>http://blog.maxaller.name/2010/07/grandparent-of-ruby-and-java-eiffel-and-friends/</link>
		<comments>http://blog.maxaller.name/2010/07/grandparent-of-ruby-and-java-eiffel-and-friends/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 07:01:36 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[musing]]></category>
		<category><![CDATA[eiffel]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.maxaller.name/?p=293</guid>
		<description><![CDATA[I'm curious about the effort involved in writing a new programming language, and hence have been doing a little research (including watching Guy Steele's now-famous and amusing Growing a Language lecture).  I know I want to target the NekoVM (primarily one of the targets of haxe, for now), but what languages should I base [...]]]></description>
			<content:encoded><![CDATA[<p>I'm curious about the effort involved in writing a new programming language, and hence have been doing a little research (including watching Guy Steele's now-famous and amusing <a target="_blank" href="http://www.catonmat.net/blog/growing-a-language-by-guy-steele/">Growing a Language</a> lecture).  I know I want to target the <a target="_blank" href="http://nekovm.org/">NekoVM</a> (primarily one of the targets of <a target="_blank" href="http://haxe.org/">haxe</a>, for now), but what languages should I base it on?  One of the languages I've heard a good deal about about, mainly based on its design-by-contract principles, is Eiffel.</p>
<p>(even if you're not interested in building a new language, learning about programming languages and their design decisions increases our understanding of them and, hopefully, our proficiency with them)<br />
<span id="more-293"></span><br />
What is Eiffel?  Is it another language that lives solely in academia?  Is there anything particularly interesting about it?</p>
<p>It's a static, strongly typed language, and...the rest of its characteristics you can read about on Wikipedia.</p>
<p>From a historical perspective, it's interesting to see some of the key features in Eiffel make their way into Java and Ruby, and to see which features didn't.</p>
<p>For example, Eiffel has a notion of abstract classes, except they're called "deferred" classes and use the <code>deferred</code> keyword.  Ruby has no abstract classes, though you could simply make the constructor throw an exception, I suppose.</p>
<p>More interestingly, Eiffel supports multiple inheritance, but neither Ruby nor Java do  (though Scala supports something similar).  How does it evade the <a target="_blank" href="http://en.wikipedia.org/wiki/Diamond_inheritance">diamond inheritance problem</a>?  Eiffel doesn't support argument overloading, like Java does; so if two parent classes have the same method, it won't compile.  Instead, you have to resolve the name conflict by renaming one or both of the conflicting parent methods in your subclass.</p>
<p>Like Java (1.5 and later, at least), you can't override a parent method without explicitly stating it, except instead of with an <code>@Override</code> annotation at the site of the override, you declare the override at the start of the class with <code>redefine</code>.</p>
<p>Like Scala, Eiffel holds the Uniform Access Principle close -- Eiffel lets you redefine an argument-less method in an ancestor as an attribute in the current class.</p>
<p>Like Scala, Eiffel has a <code>void</code> type, and it is a descendant of ALL reference types, which allows you to pass void into any function expecting a reference type.</p>
<p>Unlike Ruby, Java, and Scala, the only structuring tool is a class -- no interfaces, mixins, traits, interfaces, or modules.</p>
<p>Like Java, Eiffel has a notion of a <code>once</code> routine.  Java's equivalent is the static initializer block (static {}).  Ruby has a similar pattern, using ||=, to initialize a value once.  (Scala also has a notion of lazily evaluated methods/attributes)</p>
<p>Unlike Java, Eiffel does not allow you to cast an object to another type (though you can always try to assign one object to a variable of a type and it will 'cast' it).</p>
<p>And so on.  If this piqued your interest in the ancestor of two big languages of today, check out the <a href="http://archive.eiffel.com/doc/online/eiffel50/intro/language/tutorial-00.html" target="_blank">tutorial</a>.  The first 2-3 chapters are a bit dry and apparently a little self-absorbed in places (it's not just a language, it's a process! they say), but still a good read/skim.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2010/07/grandparent-of-ruby-and-java-eiffel-and-friends/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Destructors in Ruby?  Not quite&#8230;</title>
		<link>http://blog.maxaller.name/2009/12/destructors-in-ruby-not-quite/</link>
		<comments>http://blog.maxaller.name/2009/12/destructors-in-ruby-not-quite/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 00:54:35 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[destructor]]></category>
		<category><![CDATA[jruby]]></category>

		<guid isPermaLink="false">http://blog.maxaller.name/?p=247</guid>
		<description><![CDATA[So I was curious to see how destructors work in Ruby, and...they don't.  Or rather, the method we do have, ObjectSpace.define_finalizer, is rather restrictive.  But it does leave a loophole -- the callback method receives an object_id.

If you're thinking this is a bad idea, you might be right -- this is just a [...]]]></description>
			<content:encoded><![CDATA[<p>So I was curious to see how destructors work in Ruby, and...they don't.  Or rather, the method we do have, ObjectSpace.define_finalizer, is rather restrictive.  But it does leave a loophole -- the callback method receives an object_id.<br />
<span id="more-247"></span><br />
If you're thinking this is a bad idea, you might be right -- this is just a proof of concept showing that it's possible.  Anyway, so the main restriction on define_finalizer callback is it can't refer to the object being freed.  If you try, the callback fails silently (except on JRuby 1.4.0! the exception propagates there).  This is because the callback executes <em>after</em> the object has been freed, so there is no "self".  Here's the proof of concept of one possible solution: maintain a map of object ids to resources: <a href="http://gist.github.com/255174" target="_blank">gist</a>.  The module, sample app, and output from Ruby 1.8(.7), 1.9, and JRuby 1.4.0 are also included.</p>
<p>Edit: apparently you can embed Gists.  Sweet.  Gist is below.</p>
<p><script src="http://gist.github.com/255174.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2009/12/destructors-in-ruby-not-quite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sprockets &#8212; it&#039;s a good thing</title>
		<link>http://blog.maxaller.name/2009/02/sprockets-its-a-good-thing/</link>
		<comments>http://blog.maxaller.name/2009/02/sprockets-its-a-good-thing/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 06:23:59 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[processor]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sprockets]]></category>

		<guid isPermaLink="false">http://blog.maxaller.name/?p=72</guid>
		<description><![CDATA[Came across an interesting utility library: Sprockets.  It's a Ruby-powered Javascript preprocessor.  It's used for three things -- embedding other js files into the current js file, ensuring required assets get copied to the assets root, and for interpolating constants (like version numbers, author, etc) into the js file.  I found it [...]]]></description>
			<content:encoded><![CDATA[<p>Came across an interesting utility library: <a href="http://www.rubyinside.com/sprockets-a-ruby-powered-javascript-dependency-library-from-37signals-1520.html">Sprockets</a>.  It's a Ruby-powered Javascript preprocessor.  It's used for three things -- embedding other js files into the current js file, ensuring required assets get copied to the assets root, and for interpolating constants (like version numbers, author, etc) into the js file.  I found it browsing Prototype.js's source -- really cool stuff.  Also funny because I came across it by accident and I was just contemplating designing an identical tool.  Good thing and bad thing at the same time <img src='http://blog.maxaller.name/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2009/02/sprockets-its-a-good-thing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby 1.9 and OpenSSL on Ubuntu</title>
		<link>http://blog.maxaller.name/2009/02/ruby-19-and-openssl-on-ubuntu/</link>
		<comments>http://blog.maxaller.name/2009/02/ruby-19-and-openssl-on-ubuntu/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 02:45:12 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[openssl]]></category>
		<category><![CDATA[packages]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[ruby 1.9.1]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.maxaller.name/?p=70</guid>
		<description><![CDATA[Having trouble getting openssl working on your Linux box and Ruby 1.9 (or 1.9.1, specifically)?  Here's something to give a try...

If you got your Ruby from a package manager, you have to get an extra package before reinstalling Ruby.  If you built from source (as is currently the only way to get Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>Having trouble getting openssl working on your Linux box and Ruby 1.9 (or 1.9.1, specifically)?  Here's something to give a try...<br />
<span id="more-70"></span><br />
If you got your Ruby from a package manager, you have to get an extra package before reinstalling Ruby.  If you built from source (as is currently the only way to get Ruby 1.9.1 on Ubuntu) then you still have to get the extra package, but you don't have to reinstall Ruby.</p>
<h1>From the repository</h1>
<ol>
<li>sudo aptitude install libopenssl-ruby1.9</li>
<li>sudo aptitude install ruby1.9</li>
</ol>
<h1>From source</h1>
<ol>
<li>sudo aptitude install libopenssl-ruby1.9</li>
<li>cd ~/Downloads/ruby-1.9.1-p0/ext/openssl</li>
<li>ruby extconf.rb &#038;& make &#038;& sudo make install</li>
</ol>
<p>Note that if you haven't installed Ruby yet, you don't need to build the openssl gem manually -- I believe it will automatically get picked up during the regular Ruby 1.9.1 build process if all the dependencies are already there.</p>
<h1>Disclaimer...</h1>
<p>I'm not 100% sure these steps are accurate, so if they're not, please leave angry messages and I'll try to fix the directions.  Otherwise, hope they help!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2009/02/ruby-19-and-openssl-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>CouchDB and logs&#8230;</title>
		<link>http://blog.maxaller.name/2008/08/couchdb-and-logs/</link>
		<comments>http://blog.maxaller.name/2008/08/couchdb-and-logs/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 22:20:50 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[just for fun]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[document-oriented database]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://giftswappo.com/wordpress/?p=35</guid>
		<description><![CDATA[I've taken it upon myself to do some log analysis at my work.  This involves taking a large volume of logs (multiple gigabytes) and somehow organizing them so that the data stored within them are readily available.  This is no small task.  At present, there are thousands of individually gzipped files, and [...]]]></description>
			<content:encoded><![CDATA[<p>I've taken it upon myself to do some log analysis at my work.  This involves taking a large volume of logs (multiple gigabytes) and somehow organizing them so that the data stored within them are readily available.  This is no small task.  At present, there are thousands of individually gzipped files, and the best way to find what you're looking for is to essentially 'zcat *.gz | grep -in "session=123"' to get what you want and is, frankly, absurd.  In some types of log files, you have 15 lines that all pertain to the same log record, with each line in the format KEY=monkeyfacevalue, and in others you have everything on the same line, with key/value pairs comma delimited.  Doesn't really matter, but there are key-value pairs in both case, and no two log records necessarily have the same set of keys.  This sounded like an opportunity to try out a new type of database...CouchDB.</p>
<p>But, in the end, I think CouchDB is not the best way to solve this problem...</p>
<p><span id="more-35"></span></p>
<p>CouchDB is what's called a <strong>document-oriented database</strong>.  This is as opposed to <strong>relational databases</strong>, like MySQL, PostreSQL, Oracle, even sqlite.  For convenience I'm going to abbreviate each as DOD and RD, respectively.</p>
<p>How they differ:</p>
<ol>
<li>DODs are schema-less.  This means there are no columns/fields to speak of with size constraints.  A "document" is a record in the database, which is essentially a hashmap (or associative array if you prefer) with a couple other little features (i.e. revisioning).</li>
<li>There are no "queries" in DODs (CouchDB, at least).  If you were curious about how something without rigid structure could be fast, this is how.  Instead of queries, you have "views", which are only slightly related to views in the RD sense.  There are two types of views -- permanent views and temporary views.  A view is the result of calling a user-defined function on every record in the database -- if the function evaluates to true, the record is included in the view.  Permanent views are stored in the form of design documents within the database itself.  Every time you add or modify a record, every view function is called on that record to (re)evaluate whether that record should be included in a particular view.  Temporary views are the basically the same, but not stored permanently in a design document -- they disappear after they're used.</li>
<li>Some other things, see <a href="http://en.wikipedia.org/wiki/CouchDB">Wikipedia</a> or their <a href="http://incubator.apache.org/couchdb/">official page</a>.</li>
</ol>
<p>So here's the problem.  You can't just say "Show all blog posts by user X", because that would require you pass a variable.  Not a big deal; you create a view that returns true if the blog post belongs to that user.  But still, you have to create a view for every single user if you want to be able to select all the blog posts by any particular user -- I'd imagine that could take up a lot of space, and CPU cycles.  Alternatively, you could have a view that just returned all blog posts, and then filter through those in your application.  Neither would be that good though, I feel, but I might be missing something.</p>
<p>Similarly, in a log file, you can't say "Give me all records with session ID Y" -- you'd need a view for that, and a temporary view would have to be generated on the fly, and the permanent view...well, you'd want a permanent view for every session ID, and there could be tens of thousands of those.  Plus every time you add a new record, you'd have to run the view functions for all those on it, and that could take a while.</p>
<p>On the bright side, CouchDB doesn't have any locks in it (helps that it was written in Erlang).  This means that no matter who or how many are reading or writing, nothing will ever get blocked.  Additionally, I guess you can seamlessly distribute the contents of the database across multiple servers and get redundancy pretty easily, but I haven't looked into that tooo much.  Also, CouchDB is technically Alpha, so all of the functionality hasn't actually been implemented yet, like interfacing with Apache Lucene (a full-text indexer search thing).</p>
<p>So CouchDB looks like it has a lot of potential, but I'm not exactly sure for what, unless you never have that many documents in the database or not that many different parameters you want to be searching on.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2008/08/couchdb-and-logs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Partial success!</title>
		<link>http://blog.maxaller.name/2008/06/partial-success/</link>
		<comments>http://blog.maxaller.name/2008/06/partial-success/#comments</comments>
		<pubDate>Sat, 28 Jun 2008 16:58:03 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[distribution]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[rmagick]]></category>

		<guid isPermaLink="false">http://giftswappo.com/wordpress/?p=27</guid>
		<description><![CDATA[For a good chunk of yesterday, I was trying to ""port"" my exceedlingly simple Ruby application to Windows.  The hitch?  It uses Gosu (game engine), Chipmunk (physics engine), ImageMagick (popular graphics tool), and RMagick (wrapper for ImageMagick in Ruby).  With the help of RubyScript2Exe it almost, almost worked.  Gosu and Chipmunk [...]]]></description>
			<content:encoded><![CDATA[<p>For a good chunk of yesterday, I was trying to ""port"" my exceedlingly simple Ruby application to Windows.  The hitch?  It uses <a href="http://code.google.com/p/gosu/" target="_blank">Gosu</a> (game engine), <a href="http://wiki.slembcke.net/main/published/Chipmunk">Chipmunk</a> (physics engine), <a href="http://www.imagemagick.org/script/index.php" target="_blank">ImageMagick</a> (popular graphics tool), and <a href="http://rmagick.rubyforge.org/" target="_blank">RMagick</a> (wrapper for ImageMagick in Ruby).  With the help of RubyScript2Exe it almost, <em>almost</em> worked.  Gosu and Chipmunk had no problem, as they had no-strings-attached .so files and apparently were programmed well.  ImageMagick, despite trying to be a pain in the ass by making me include an extra dozen DLLs in my project folder, actually did end up working.  But RMagick...when moving the generated app to a new computer that didn't have ImageMagick installed freaked out with a weird "address not accessible" error or something.  After some fiddling I gave it up as a lost cause and dropped support for ImageMagick+RMagick.  The only reason they were there in the first place is because I wanted to load SVG files whenever possible, and possibly have some dynamic graphic generation, but...the former isn't that great anyway, and the latter will have to be done other ways, if at all.</p>
<p>So, yes, Ruby+Gosu+Chipmunk play just fine with RubyScript2Exe on both Windows and Linux.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2008/06/partial-success/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Distributing Ruby Apps</title>
		<link>http://blog.maxaller.name/2008/06/distributing-ruby-apps/</link>
		<comments>http://blog.maxaller.name/2008/06/distributing-ruby-apps/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 18:48:27 +0000</pubDate>
		<dc:creator>Max</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[distributing]]></category>
		<category><![CDATA[gosu]]></category>

		<guid isPermaLink="false">http://giftswappo.com/wordpress/?p=26</guid>
		<description><![CDATA[So I'm pondering the idea of writing a game...but I want it to be playable on Windows and Linux, and I want it to be available on Linux without much trouble.  I've made a couple interesting discoveries, in terms of applications to help me do this.

The first is called RubyScript2Exe.  It takes all [...]]]></description>
			<content:encoded><![CDATA[<p>So I'm pondering the idea of writing a game...but I want it to be playable on Windows and Linux, and I want it to be available on Linux without much trouble.  I've made a couple interesting discoveries, in terms of applications to help me do this.</p>
<p><span id="more-26"></span></p>
<p>The first is called <a href="http://www.erikveen.dds.nl/rubyscript2exe/">RubyScript2Exe</a>.  It takes all the files needed by an application and sticks it into a single binary executable, as well as any dependencies.  Cool huh?  The only problem is the smallest program RubyScript2Exe can generate is 700k.  Not so bad, but then I include the Gosu game library I'm using and it comes out to 7.0M.  Compressing (7z, tar.gz, zip) doesn't get it past 6.7M.  Oh well, after adding all the media and stuff I want I can't imagine it getting past 15M or 20M, which is acceptable when most people have &gt;100 gigs of space.  But not everyone has uber broadband...oh well.  Anyway, it just seems larger than it needs to be is all.</p>
<p>The other application (by the same guy I think) is <a href="http://www.erikveen.dds.nl/tar2rubyscript/index.html">Tar2RubyScript</a>.  Tar2RubyScript does something similar to RubyScript2Exe, but instead of generating a binary, it generates a Ruby script.  That is, it takes your directory tree of files and generates a single equivalent .rb file.  Cool huh?  It's like JAR files, but with less overhead and without compression.</p>
<p>So, ultimately, Windows will have just the binary and Linux will have a binary (for those without Ruby), the single Ruby script (for people who don't care about the source), and the full directory tree (for the inquisitive and those who can't get the other script to work).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.maxaller.name/2008/06/distributing-ruby-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
