Recently in programming Category

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 unstable than on windows. (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: Test if the installation worked: Compile readline to get arrow keys support in IRB: Now ruby 1.9.1 without valgrind is installed. Next install valgrind: Now setup another ruby installation with valgrind support. Then add some handy shortcuts: For more information see: UPDATE: Added --enable-shared to RUBY_OPTIONS
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:

You can just do this:

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.

My current solution is this:

You use it like this:
Warning: You need mysql 5.1 so that LAST_INSERT_ID(id) works. (Mysql bug)

ActionExtension for rails

| No Comments | No TrackBacks
In my rails application i often have this kind of code in my erb/haml files:
There is some repetition in it. Why not infer the i18n-key from the action? My approach:
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)
Some of these ideas are relatively easy to implement:
Requirements:
  • Each model needs an class-method called 'actions'
  • Each model needs an instance-method called 'actions'
  • The actions-methods return an proxy (ActionProxy) that records the method name that is invoked on it (method name = action name)
  • the proxy returns an information object (ActionInformation) that contains:
    1. the instance or the class of the model
    2. the action name
    3. the parameters
  • the ActionInformation has methods that infer the i18n key as well as the url

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

Haml modification for i18n

| No Comments | No TrackBacks

I'm using the haml plugin in my rails application. In haml you can output plaintext like this:

Since i never output plaintext in my view because i use i18n i decided to modify haml:

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

The modification is quick & dirty and just a few lines long:
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:
This assumes that '_' is the method that is used for i18n. You can even append parameters:
This invokes _('my.i18n.key.here',:param1 => 'value')

Ruby DataFormat

| No Comments | No TrackBacks
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: 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. 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: 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.
The different types that are currently available to describe a data format:

Supported types
NumberSerializer: short, int, long (+unsigned: ushort etc.), float, double
uint :attribute_name, :min => 1145, :max => 67546 
StringSerializer: nullterminated(default) or fixed-length
string :attr_name, :length => 32
MagicSerializer: throws exception when the magic value (in this case 1337) is not found at the pecific position
magic :magic_number, :value => 1337
ArraySerializer: reads an array from the file. The data format of each entry can be specified.
array(:things,:length => :arr_length) do
	int :thing_id
	float :value
end


Status
Experimental version.
Todo:
  • Option to specify if format is big- or little-endian
  • Store errors (eg: integer out of range) in an error hash like in active record
  • Optional elements (if :someattr == 0, then :otherattr is not present)
  • Skip sections (if :someattr == 0, then skip x bytes)