<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>ragmaanir</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/" />
    <link rel="self" type="application/atom+xml" href="http://ragmaanir.mypresident.de/atom.xml" />
    <id>tag:ragmaanir.mypresident.de,2009-04-18://1</id>
    <updated>2010-04-19T13:36:49Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.24-de</generator>

<entry>
    <title>Grammy: Ruby Recursive Descent Parser Generator</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2010/04/grammy-ruby-recursive-descent-parser-generator.html" />
    <id>tag:ragmaanir.mypresident.de,2010://1.16</id>

    <published>2010-04-19T13:07:21Z</published>
    <updated>2010-04-19T13:36:49Z</updated>

    <summary>Grammy is a very small recursive descent parser generator framework written in ruby. It has several similarities with boost::spirit. Short example: g = Grammy.define :letters do rule lower: &apos;a&apos;..&apos;z&apos; rule upper: &apos;A&apos;..&apos;Z&apos; rule letter: :lower | :upper start word: +:letter...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
    <category term="rubyrecursivedescentparsergeneratorboostspiritgraphvizabstractsyntaxtree" label="ruby recursive descent parser generator boost spirit graphviz abstract syntax tree" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[<p>Grammy is a very small recursive descent parser generator framework written in ruby. It has several similarities with boost::spirit. </p>

<p><strong>Short example:</strong>
<textarea name='code' class='ruby'>
g = Grammy.define :letters do
    rule lower: 'a'..'z'
    rule upper: 'A'..'Z'
    rule letter: :lower | :upper
    start word: +:letter
end
</textarea></p>

<p>You can use the defined grammar to parse strings:</p>

<p><textarea name='code' class='ruby'>
result = g.parse("ALongWord")
result.full_match? #=> true
result.to_image("test") # creates a .png with graphviz, graphviz is required for that
</textarea></p>

<p>An example image (not for this grammar):</p>

<p><img src="/images/example_ast.png" alt="error: image not loaded" title="" /></p>

<p>Grammy supports:</p>

<ul>
<li>Most EBNF features: Sequences, Repetition, Alternatives, Optional rules</li>
<li>Shortcut for lists: list and list?</li>
<li>Skipping of characters: comments, whitespaces between words</li>
<li>Generation of an AST. Most unused tokens can be removed automatically.</li>
<li>AST can be written to an image file with help of graphviz.</li>
</ul>

<p>You can get grammy at github: <a href="http://github.com/Ragmaanir/grammy">Grammy on github</a></p>

<p>There is also a more detailed description there.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Problem Graphs</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/12/problem-graphs.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.15</id>

    <published>2009-12-01T00:48:20Z</published>
    <updated>2009-12-01T01:07:23Z</updated>

    <summary>This is an idea i came up with during analyzing problems while designing software. A specific software-design has/causes several problems. Those problems have zero or more (alternative) solutions. These solutions are basically changes to the previous software design that caused...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
    <category term="problemgraph" label="problem graph" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="problemmodeling" label="problem modeling" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="softwareanalysis" label="software analysis" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="softwaredesign" label="software design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="theory" label="theory" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[<p>This is an idea i came up with during analyzing problems while designing software.</p>

<p>A specific software-design has/causes several problems. Those problems have zero or more (alternative) solutions. These solutions are basically changes to the previous software design that caused the problem. The new software design that solves one or more problems of the initial design can again cause problems, but the problem that was solved with the solution wont be caused (otherwise the solution was not a real solution for the problem).</p>

<p>An example for a problem-graph:</p>
<img src="/images/problemgraph_1.png" />

<p>So, a problem has several *alternative* solutions and a solution causes several problems (at once - they are not alternatives).</p>

<big><b>Dilemma</b></big>
<p>
A cyclic problem-solution situation i call "dilemma", because it cant be solved by a specific solution:
</p>

<img src="/images/problemgraph_2.png" />

<p>Problem A can be solved with Solution A, which causes problem B, which in turn can be solved by the solution B, which causes problem A. You either solve A with solution A or B with solution B, but you cant solve both.</p>

<p>This does not imply that those problems cant be solved. There might be an alternative solution A2 (which has not been discovered yet) to solution A which does not cause problem B. But for this problem graph you can say: "Solving problem A with solution A leads into a dilemma".</p>

<p><big><b>Extensions</b></big></p>

<b>Weights</b>
<p>The problem graph idea can be extended:
You can assign weights to the arrows. Without weights the causalities can be interpreted as:</p>
<ul>
	<li>"The problem P is completely solved by the solution S"</li>
	<li>"The solution S causes exactly the problems P1 .. Pn"</li>
</ul>

<p>With weights added it can be interpreted like this:</p>
<ul>
	<li>"The problem P is weakly solved by solution S"</li>
	<li>"The solution S strongly causes problem P1 and weakly causes problem P2"</li>
</ul>

<p>With these weights you can model non-exact problem relations like:</p>
<ul>
	<li>"Spamming can be strongly reduced by introducing captchas"</li>
	<li>..</li>
</ul>

<b>Colors</b>
<p>The problems can be weighted (colored) too, so that you can say "problem X is much more costly than problem Y".</p>

<p><i>This can easily be extended (eg design algorithms that find optimal solutions for a problem graph etc) but at the moment im too busy.</i></p>
]]>
        
    </content>
</entry>

<entry>
    <title>Compiling and installing ruby 1.9.1 on Ubuntu 9.04 with valgrind</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/08/compiling-and-installing-ruby-191-on-ubuntu-904-with-valgrind.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.14</id>

    <published>2009-08-23T13:42:20Z</published>
    <updated>2009-09-08T22:26:22Z</updated>

    <summary>Just recently i switched from windows XP to ubuntu 9.04. I had some problems (Ubuntu freezes when connecting to WLAN) with my wlan drivers (DLink DWA 547) but after installing the compat-wireless package it worked. But its slower and more...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
        <category term="programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="jauntyjackalope" label="jaunty jackalope" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby191" label="ruby 1.9.1" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ubuntu904" label="ubuntu 9.04" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="valgrind" label="valgrind" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[Just recently i switched from windows XP to ubuntu 9.04. I had some problems (Ubuntu freezes when connecting to WLAN) with my wlan drivers (DLink DWA 547) but after installing the compat-wireless package it worked. <strike>But its slower and more unstable than on windows.</strike> (After upgrading ubuntu and recompiling the package WLAN works as good as on windows).

I tried to install ruby 1.9.1 on ubuntu. After several hours of reading articles and googling i put together these install instructions:

<textarea name="code" class="ruby">
sudo apt-get install build-essential
sudo aptitude install zlib1g
sudo aptitude install zlib1g-dev

RUBY_FILE = ruby-1.9.1-p243
RUBY_SRC = /usr/local/src/$RUBY_FILE

cd /usr/local/src
sudo wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/$RUBY_FILE.tar.bz2
sudo tar xvf $RUBY_FILE.tar.bz2
cd $RUBY_SRC

# maybe try --disable-pthread : http://timetobleed.com/fix-a-bug-in-rubys-configurein-and-get-a-30-performance-boost/
# several more options available
RUBY_OPTIONS="--enable-shared --disable-install-doc" 

sudo ./configure $RUBY_OPTIONS
sudo make && make install
</textarea>

Test if the installation worked:
<textarea name="code" class="ruby">
$ ruby -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [x86_64-linux]
</textarea>

Compile readline to get arrow keys support in IRB:
<textarea name="code" class="ruby">
# install readline for irb (arrow keys)
sudo apt-get install libreadline5 libreadline5-dev
cd $RUBY_SRC/ext/readline
sudo ruby extconf.rb
sudo make
sudo make install
cd ~
</textarea>

Now ruby 1.9.1 <i>without</i> valgrind is installed.
Next install valgrind:
<textarea name="code" class="ruby">
VALGRIND_FILE = valgrind-3.4.1
cd /usr/local/src
sudo wget http://valgrind.org/downloads/$VALGRIND_FILE.tar.bz2
sudo tar xvf $VALGRIND_FILE.tar.bz2
cd $VALGRIND_FILE
sudo ./configure
sudo make
# make check
sudo make install
cd ~
</textarea>

Now setup another ruby installation with valgrind support.
<textarea name="code" class="ruby">
cd $RUBY_SRC
sudo ./configure $RUBY_OPTIONS --with-valgrind --prefix=/opt/ruby-debug
sudo make
sudo make install
cd ~
</textarea>

Then add some handy shortcuts:
<textarea name="code" class="ruby">
ln -s /opt/ruby-debug/bin/ruby /usr/local/bin/ruby-debug 
ln -s /opt/ruby-debug/bin/gem /usr/local/bin/gem-debug
</textarea>

For more information see:
<ul>
<li>
<a htef="http://sandeep.wordpress.com/2009/05/06/a-clean-install-of-ruby-191-ruby-on-rails-232-on-ubuntu-904/">Ruby 1.9.1 installation</a>
</li>
<li><a href="http://blog.evanweaver.com/articles/2008/02/05/valgrind-and-ruby/">Valgrind and Ruby</a>
</li>
<li><a href="http://forum.webbynode.com/topic.php?id=56">Ubuntu 9.04: Installing Ruby 1.9 with RubyGems from Source</a></li>
<li><a href="http://blog.fiveruns.com/2008/3/3/compiling-ruby-rubygems-and-rails-on-ubuntu">Compiling Ruby, RubyGems and Rails on Ubuntu</a></li>
<li><a href="http://vinsol.com/blog/2007/07/11/how-to-make-arrow-keys-working-in-irb-in-linuxubuntu/">How to make arrow keys working in irb in Linux/Ubuntu</a></li>
</ul>

UPDATE: Added --enable-shared to RUBY_OPTIONS
]]>
        
    </content>
</entry>

<entry>
    <title>Rails Safe</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/06/rails-safe.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.13</id>

    <published>2009-06-27T19:16:25Z</published>
    <updated>2009-07-15T13:31:05Z</updated>

    <summary>Because i am a bit paranoid i sometimes think about protecting my ROR-sourcecode. I came up with this idea:* Encrypt all files (models,controllers,helpers,views,css,...) with a secret key.* Upload the encrypted files on your server* Put the key in a file...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
    <category term="rubyrailssafesecurity" label="ruby rails safe security" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[Because i am a bit paranoid i sometimes think about protecting my ROR-sourcecode. I came up with this idea:<br /><br />* Encrypt all files (models,controllers,helpers,views,css,...) with a secret key.<br />* Upload the encrypted files on your server<br />* Put the key in a file and upload the file to config/<br />* When the rails app starts, load the key into memory and delete(!) the key file<br />* Decrypt files (in memory) of your app when they are loaded<br /><br />An attacker that got access to the filesystem can't just copy the source since it is encrypted. One problem might be this:<br />The attacker got write access to the FS and creates a .rb somewhere in a loaded gem or in the rails app. Then he might be able to read out the key and decrypt the source files.<br /><br />The best way i know to protect the source is to use JRuby and compile the rails app to a jar.<br /> ]]>
        
    </content>
</entry>

<entry>
    <title>Rails extension for mysql insert or update</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/05/rails-extension-for-mysql-insert-or-update.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.12</id>

    <published>2009-05-20T14:31:16Z</published>
    <updated>2009-06-27T19:05:04Z</updated>

    <summary>Mysql has a special &apos;INSERT ... ON DUPLICATE KEY UPDATE&apos; statement which can be used for some models like e.g. ratings. Instead of something similar to this: if m = Model.find(...) m.update else m = Model.new(params) m.save! end You can...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
        <category term="programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="activerecord" label="active record" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="extension" label="extension" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="insertorupdate" label="insert or update" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mysql" label="mysql" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rails" label="rails" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[Mysql has a special 'INSERT ... ON DUPLICATE KEY UPDATE' statement which can be used for some models like e.g. ratings. Instead of something similar to this:<br/>
<textarea name='code' class='ruby'>
if m = Model.find(...)
    m.update
else
    m = Model.new(params)
    m.save!
end
</textarea><br/>
You can just do this:
<textarea name='code' class='ruby'>
m = Model.new(params)
m.save!
</textarea><br/>
<p>when the row already exists in the database (detected by a unique-constraint violation) the values of that row are updated and saved, otherwise the new row is created.</p>
My current solution is this: <br/>
<textarea name='code' class='ruby'>
module InsertOrUpdate
	
	def create
		create_or_update_impl
    end
	
	def update
		create_or_update_impl
    end
	
	def create_or_update_impl
		attrs = attributes_with_quotes(false,false)
		
		unless attrs.empty?
			self.id = connection.insert <<-end_sql ,"#{self.class.name} Create or update"
				INSERT INTO #{self.class.quoted_table_name} (#{quoted_column_names(attrs).join(', ')}) 
				VALUES(#{attrs.values.join(', ')}) 
				ON DUPLICATE KEY UPDATE 
					#{update_values_partial},
					id = LAST_INSERT_ID(id)
			end_sql
        end
		
		@new_record = false
		self.id
    end
	
	# returns "attr1 = 'value1', attr2 = 'value2', ..."
	def update_values_partial
		attrs = attributes_with_quotes(false,false)
		
		attrs.collect{|attr,value| "#{attr}=#{value}" }.join(",")
    end
	
	module ClassMethods
		def insert_or_update
			include InsertOrUpdate
        end
    end
	
end

ActiveRecord::Base.extend(InsertOrUpdate::ClassMethods)
</textarea><br/>

You use it like this:
<textarea name='code' class='ruby'>
class Model < ActiveRecord::Base
	insert_or_update # this includes the module and overwrites the default create and update methods
end
</textarea><br/>

<b>Warning:</b> You need mysql 5.1 so that LAST_INSERT_ID(id) works.
(<a href="http://bugs.mysql.com/bug.php?id=27033">Mysql bug</a>)]]>
        
    </content>
</entry>

<entry>
    <title>ActionExtension for rails</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/05/actionextension-for-rails.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.11</id>

    <published>2009-05-20T13:18:52Z</published>
    <updated>2009-05-23T15:00:34Z</updated>

    <summary>In my rails application i often have this kind of code in my erb/haml files: button_to &quot;CommentRating.actions.create&quot;,comment_ratings_path, :rating =&gt; CommentRating::Good, :comment_id =&gt; @comment.id button_to &quot;Comment.actions.destroy&quot;, @comment, :method =&gt; :delete There is some repetition in it. Why not infer the i18n-key...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
        <category term="programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="actionextension" label="action extension" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rails" label="rails" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[In my rails application i often have this kind of code in my erb/haml files:
<textarea name='code' class='ruby'>
button_to "CommentRating.actions.create",comment_ratings_path, :rating => CommentRating::Good, :comment_id => @comment.id
button_to "Comment.actions.destroy", @comment, :method => :delete
</textarea><br/>
There is some repetition in it. Why not infer the i18n-key from the action? My approach:
<textarea name='code' class='ruby'>
button_to CommentRating.actions.create(:rating => CommentRating::Good, :comment_id => @comment.id)
button_to @comment.actions.destroy, :method => :delete

# or even better
button_to CommentRating.actions.create(:rating => :good, :comment => @comment)
button_to @comment.actions.destroy # method is inferred from action
</textarea><br/>
The parameters should also be passed to the i18n key. So for the first button_to call the translation method is invoked with: _('CommentRating.actions.create',:rating => :good, :comment => @comment)
<br/>
Some of these ideas are relatively easy to implement:<br/>
Requirements:
<ul>
<li>Each model needs an class-method called 'actions'</li>
<li>Each model needs an instance-method called 'actions'</li>
<li>The actions-methods return an proxy (ActionProxy) that records the method name that is invoked on it (method name = action name)</li>
<li>the proxy returns an information object (ActionInformation) that contains:
  <ol>
  <li>the instance or the class of the model</li>
  <li>the action name</li>
  <li>the parameters</li>
  </ol>
</li>
<li>the ActionInformation has methods that infer the i18n key as well as the url</li>
</ul>

<textarea name='code' class='ruby'>

# Comment.actions.new #=> determines url, i18n key and parameters
# @comment.actions.destroy #=> determines url with id of @comment
# CommentRating.actions.create(:rating => :good, :comment_id => @comment.id)
module ActionExtension

	# An instance of this class is returned when Comment.actions.new is called
	class ActionInformation
		attr_reader :instance, :klass, :action, :params

		def initialize(options)
			@instance, @klass, @params, @action = options[:instance],options[:class],options[:params], options[:action]
			@klass = @instance.class if @instance
		end

		def i18n_key
 			# TODO parameter handling
			["#{klass.model_name}.actions.#{action}",params.first]
		end

		def controller
			klass.model_name.plural
		end

		def url
			url = {:controller => controller, :action => action}
			url.merge!(:id => @instance.to_param) if @instance
			# TODO parameter handling: current solution: merge hash into url; better: add hidden fields
			url.merge!(@params.first) if @params.any? and @params.first.is_a? Hash
			url
		end
	end

	# proxy = @comment.actions #=> InstanceActionProxy(@comment)
	# proxy.rate(:good) #=> InstanceActionProxy(@comment).method_missing
	class ActionsProxy
		def initialize(options)
			raise unless options.is_a? Hash
			@options = options.dup
		end

		def method_missing(meth,*params)
			ActionInformation.new(@options.merge!(:action => meth, :params => params))
		end
	end

	# called when included in ActiveRecord::Base
	def self.included(base)
		base.class_eval do
			# called when Model inherits from ActiveRecord::Base
			def self.inherited(child)
				#child.extend(ActionDefinition)
				child.class_eval do
					def actions
						ActionsProxy.new(:instance => self)
					end

					def self.actions
						ActionsProxy.new(:class => self)
					end
				end
				super
			end
		end
	end

end

ActiveRecord::Base.send(:include,ActionExtension)
</textarea><br/>

Now this can be used like this:
<textarea name='code' class='ruby'>
info = Comment.actions.create(:param => 1)
info.i18n_key #=> ['Comment.actions.create',{:param => 1}]
info.url #=> {:controller => 'comments', :action => 'create', :param => 1}

info = @comment.actions.destroy
info.i18n_key #=> ['Comment.actions.destroy']
info.url #=> {:controller => 'comments', :action => 'destroy', :id => @comment.to_param}
</textarea><br/>

Improvements to work on:
<ul>
<li>infer method (:delete etc)</li>
<li>dont merge the parameters into the url. make them accessible seperately so they can be extracted and posted via hidden fields inside a form.</li>
<li>maybe redefine actions in the models to preprocess the parameters: define_action :rate => lambda{|*params| {:rating => params[1]} }</li>
</ul>]]>
        
    </content>
</entry>

<entry>
    <title>Haml modification for i18n</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/05/haml-modification-for-i18n.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.10</id>

    <published>2009-05-20T12:54:38Z</published>
    <updated>2009-05-20T13:14:35Z</updated>

    <summary>I&apos;m using the haml plugin in my rails application. In haml you can output plaintext like this: %div plaintext here Since i never output plaintext in my view because i use i18n i decided to modify haml: %div my.i18n.key.here So...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
        <category term="programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="haml" label="haml" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="i18n" label="i18n" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="l10n" label="l10n" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="modification" label="modification" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="rails" label="rails" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[<p>I'm using the <a href="http://haml.hamptoncatlin.com/">haml plugin</a> in my rails application. In haml you can output plaintext like this:
<textarea name="code" class="ruby">
%div plaintext here
</textarea><br/></p>

<p>Since i never output plaintext in my view because i use i18n i decided to modify haml:
<textarea name="code" class="ruby">
%div my.i18n.key.here
</textarea><br/></p>

<p>So instead of outputting plaintext, you supply a i18n-key and haml outputs the translated text that belongs to that key.</p>

<p>The modification is quick &amp; dirty and just a few lines long:</br>
Go to the haml precompiler.rb and find the render_tag method.
There should be a 'switch action' switch.
Add the following lines to the switch:
<textarea name="code" class="ruby">
switch action
    #[...]
    when '', nil
        if not value.blank?
            parse = true
            key, params = value.scan(/\A[^,]+|[^,].*\Z/)
            params = ',' + params unless params.blank?
            value = "_('#{key}'#{params})"
        end
    end
    #[...]
end
</textarea><br/>
This assumes that '_' is the method that is used for i18n.
You can even append parameters:
<textarea name="code" class="ruby">
%div my.i18n.key.here, :param1 => 'value'
</textarea><br/>
This invokes _('my.i18n.key.here',:param1 => 'value')</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Ruby DataFormat</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/04/ruby-dataformat.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.9</id>

    <published>2009-04-18T16:11:29Z</published>
    <updated>2009-04-18T17:10:34Z</updated>

    <summary>For one project i am currently working on i had to load and parse some binary files with ruby. The parser code was not very nice, so i came up with an idea: d = DataFormat.description do int :the_id float...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
        <category term="programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="dataformat" label="dataformat" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[For one project i am currently working on i had to load and parse some binary files with ruby. The parser code was not very nice, so i came up with an idea:

<textarea name="code" class="ruby">d = DataFormat.description do
	int :the_id
	float :value
end

# binary data in the stream: int(1337)float(-0.1337)
data = d.read_from(stream)
data.the_id #=&gt; 1337
data.value #=&gt; -0.1337
</textarea>

The cool thing about this is: The DataFormat is a description of the data format and the code to load and save a file in this data format is generated automatically. So you dont have to worry about the loading and saving code, you just have to specify the format.

Some more examples:
This one reads an array of values.
<textarea name="code" class="ruby">d = DataFormat.description do
	uint :arr_length

	array(:things,:length =&gt; :arr_length) do
		int :thing_id
		float :value
	end
end

# stream: int(2)int(4363)float(0.5)int(66584)float(-1677.5)
data = d.read_from(stream) 

data.arr_length #=&gt; 2
data.things[0].thing_id #=&gt; 4363
data.things[0].value #=&gt; 0.5

data.things[1].thing_id #=&gt; 66584
data.things[1].value #=&gt; -1677.5
</textarea>

The data that is returned is an instance of the class AttributeHash. The AttributeHash just wraps an hash and overwrites method_missing to delegate all attribute accesses to the wrapped hash (so it behaves like a javascript object).
But you can specify that an instance of some custom class should be created instead of an AttributeHash. Example:
<textarea name="code" class="ruby">class ItemList
	attr_accessor :name, :max_size, :items
end
class Item
	attr_accessor :value
end

d = DataFormat.description do
	string :name
	uint :max_size

	array(:items,:class =&gt; Item) do
		string :value
	end
end

data = d.read_from(stream,:object =&gt; ItemList.new)

data.class #=&gt; ItemList
data.items[0].class #=&gt; Item
data.items[0].value #=&gt; "yes"
data.items[1].class #=&gt; Item
data.items[1].value #=&gt; "no"
</textarea>
The requirement for the class that will be instantiated is just that is must have methods for "attrname=" calls with "attrname" specified in the data format.

<br />The different types that are currently available to describe a data format:<br /><br />
<strong>Supported types</strong><br />
NumberSerializer: short, int, long (+unsigned: ushort etc.), float, double <br />
<pre name="code" class="ruby">uint :attribute_name, :min =&gt; 1145, :max =&gt; 67546 
</pre>

StringSerializer: nullterminated(default) or fixed-length <br />
<pre name="code" class="ruby">string :attr_name, :length =&gt; 32
</pre>

MagicSerializer: throws exception when the magic value (in this case 1337) is not found at the pecific position<br />
<pre name="code" class="ruby">magic :magic_number, :value =&gt; 1337
</pre>

ArraySerializer: reads an array from the file. The data format of each entry can be specified.
<pre name="code" class="ruby">array(:things,:length =&gt; :arr_length) do
	int :thing_id
	float :value
end
</pre>
<br /><br />
<strong>Status</strong><br />
Experimental version.<br />
Todo:<br />
<ul>
<li>Option to specify if format is big- or little-endian</li>
<li>Store errors (eg: integer out of range) in an error hash like in active record</li>
<li>Optional elements (if :someattr == 0, then :otherattr is not present)</li>
<li>Skip sections (if :someattr == 0, then skip x bytes)</li>
</ul>]]>
        
    </content>
</entry>

<entry>
    <title>Test for ruby syntax highlighting with SyntaxHighlighter</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/04/test.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.7</id>

    <published>2009-04-18T15:09:01Z</published>
    <updated>2009-04-18T16:09:36Z</updated>

    <summary>Test syntax highlighting: class Hash # h = {:a =&gt; 1, :b =&gt; 2} # h.extract_hash!(:a).should == {:a =&gt; 1} # h.should == {:b =&gt; 2} def extract_hash!(*keys) keys = keys.first if keys.first.kind_of? Array extracted = collect{|key,value| keys.member? key} self.reject!{|key,value|...</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[Test syntax highlighting:<br />
<textarea name="code" class="ruby" cols="60" rows="10">
class Hash
	# h = {:a => 1, :b => 2}
	# h.extract_hash!(:a).should == {:a => 1}
	# h.should == {:b => 2}
	def extract_hash!(*keys)
		keys = keys.first if keys.first.kind_of? Array
		extracted = collect{|key,value| keys.member? key}
		self.reject!{|key,value| keys.member? key }
		extracted
	end
end
</textarea>

See: <a href="http://www.maxhorvath.com/2008/03/syntax-highlighting-for-your-movable-type-blog.html">Max Horvath - Syntax Highlighting for your Movable Type blog</a>]]>
        
    </content>
</entry>

<entry>
    <title>Blog created</title>
    <link rel="alternate" type="text/html" href="http://ragmaanir.mypresident.de/2009/04/blog-created.html" />
    <id>tag:ragmaanir.mypresident.de,2009://1.6</id>

    <published>2009-04-18T14:44:35Z</published>
    <updated>2009-04-18T14:46:41Z</updated>

    <summary>Blog created....</summary>
    <author>
        <name>ragmaanir</name>
        
    </author>
    
    
    <content type="html" xml:lang="de" xml:base="http://ragmaanir.mypresident.de/">
        <![CDATA[Blog created.<br /><br /><br /> ]]>
        
    </content>
</entry>

</feed>

