04.16.2009 07:45 | Comments (0)
I’ve had a problem when executing compiled Haskell-programs on Linux boxes running with older kernel versions. When executing the program, the following output appeared:
<program_name>: timer_create: Invalid argument
After messing around with strace and objdump I’ve tried to modify the first parameter of timer_create in the binary file with a hex-editor. The previous value for this was CLOCK_PROCESS_CPUTIME_ID (0x2), which is the high-resolution timer from the CPU. On my 2.6.9 box this obviously didn’t work, so I changed the value to CLOCK_REALTIME (0x0) using a text-editor. To find the correct instruction I looked at the objdump output and searched it for timer_create, which lead me to the following line:
8134935: c7 04 24 02 00 00 00 mov DWORD PTR [esp],0x2
813493c: e8 3b 55 f1 ff call 8049e7c <timer_create@plt>
8134941: 85 c0 test eax,eax
So I’ve opened the binary file with VIM, and converted it with :%!xxd to something I could actually edit with VIM. Then I searched the address e83b 55f1 and eventually found it. Before this address I’ve changed the first 0200 value to 0000 and then executed :%!xxd -r to convert the stuff back to the original binary.
After writing my changes back to disk, the program executed without problems :).
03.01.2009 22:46 | Comments (1)
I’ve been playing around with Haskell and HAppS recently using the amazing HStringTemplate library. HStringTemplate is, as you might have already guessed, a template library for Haskell, which you can use not only for web development but also for various other things. In fact it’s not really bundled with HAppS, because HAppS doesn’t ship with any template library, so it’s up to you which one you choose or whether you use one at all.
To make a long story short: I wanted to give you some tips using HStringTemplate, which I found useful and I wished I have known when I got started with it.
Displaying regular text
The simplest possible usage of HStringTemplate is the rendering of a single variable in the template.
A simple example could look like
1
2 module SimpleTest
3 where
4
5 import Text.StringTemplate
6 import Maybe
7
8 loadDirGroup :: (Stringable a) => IO (STGroup a)
9 loadDirGroup = directoryGroup "templates"
10
11 main = do
12 dirs <- loadDirGroup
13 let tpl = fromJust $ getStringTemplate "simple" dirs
14 putStrLn $ render $ setAttribute "world" "test" tpl
The ‘simple.st’ template, which must be located in the templates-directory relatively to the execute-path of the program, might look like:
1
2 hello $world$
The output of the program now is
hello test
since $world$ gets replaced by the string “test”.
Rendering lists
With StringTemplate it is also easy to render lists of elements, like e.g. lists of strings. A simple demo-program in haskell looks like:
1
2 module ListTest
3 where
4
5 import Maybe
6 import Text.StringTemplate
7
8 loadDirGroup :: (Stringable a) => IO (STGroup a)
9 loadDirGroup = directoryGroup "templates"
10
11 main :: IO ()
12 main = do
13 dirs <- loadDirGroup
14 let tpl = fromJust $ getStringTemplate "list" dirs
15 putStrLn $ render $ setAttribute "list" [ "abc", "def", "ghi" ] tpl
The appropriate template might look like:
1
2 t: $list:{elem|
3 $elem$ - $i$}$
It walks through each element in the list and prints the element and the index of the element in the list. Thus the output of the program looks like:
test:
abc - 1
def - 2
ghi - 3
It is actually possible to reference the element of the list with a special ‘it’-variable if no explicit variable name is given, which is similar to blocks in the Groovy programming language.
So you can also write:
1
2 t: $list:{
3 $it$ - $i$}$
Rendering other templates
Usually, if you are working on a web application you are splitting your templates up into subtemplates. This is of course also possible in HStringTemplate. A simple example in which elements of a list are each rendered in a sub-template might look like this:
1
2 module SubTest
3 where
4
5 import Maybe
6 import Text.StringTemplate
7
8 loadDirGroup :: (Stringable a) => IO (STGroup a)
9 loadDirGroup = directoryGroup "templates"
10
11 main :: IO ()
12 main = do
13 dirs <- loadDirGroup
14 let tpl = fromJust $ getStringTemplate "list2" dirs
15 putStrLn $ render $ setAttribute "list" [ "abc", "def", "ghi" ] tpl
The first template (‘list2.st’) within the templates directory looks like:
1
2 test: $list:{elem| $listElem()$}$
It renders for each element the ‘listElem.st’ template within the templates directory. In our example the listElem.st template is very simple:
1
2 Sub: $elem$
The program prints, as expected, the following list:
test: Sub: abc
Sub: def
Sub: ghi
Rendering objects
Another very useful feature is the automatic rendering of abstract data type objects. The only thing you must do is to derive them from Typeable and Data, so that HStringTemplate can read some meta-information about your types. Each field of the type can now be accessed in the template, similar to Django’s template engine. A simple example might look like:
1
2 {#- LANGUAGE DeriveDataTypeable #-}
3 module ObjectTest
4 where
5
6 import Text.StringTemplate
7 import Text.StringTemplate.GenericStandard
8 import Data.Generics
9 import Maybe
10
11 loadDirGroup :: (Stringable a) => IO (STGroup a)
12 loadDirGroup = directoryGroup "templates"
13
14 data Testing = Testing { val1 :: Double
15 , val2 :: Integer
16 , val3 :: String
17 } deriving (Show, Typeable, Data)
18
19 sampleElements :: [Testing]
20 sampleElements = map genTesting [1..10]
21 where genTesting n = Testing (fromInteger n) n ("test" ++ show n)
22
23 main :: IO ()
24 main = do
25 dirs <- loadDirGroup
26 let tpl = fromJust $ getStringTemplate "object" dirs
27 putStrLn $ render $ setAttribute "list" sampleElements tpl
Our Testing type is derived from Typeable and Data. In Text.StringTemplate.GenericStandard each type which is an instance of Data is made an instance of ToSElem, which allows us to pass the type to setAttribute.
The template looks like:
1
2 test: $list:{elem|
3 $elem.('val1')$ - $elem.('val2')$ - $elem.('val3')$}$
The fields of the elements can be conveniently accessed via a object.(‘fieldname’)
There are a lot of other useful features in HStringTemplate, so I’d recommend you to check out the documentation and maybe read through the code.
03.01.2009 22:40 | Comments (0)
Recently I’ve upgraded this blogging software to Merb 1.0. But since the newest Merb version requires at least Ruby 1.8.6 and Debian 4.0 ships only with Ruby 1.8.5 and I still wanted to use the 1.8.5 version for some scripts I’ve got a problem. Fortunately there is a way to install multiple coexisting Ruby versions on Debian:
Installing the New Version
First of all you should grab the most recent Ruby version on http://ruby-lang.org. Then make shure that you have all the dependencies needed for compiling Ruby installed. You can verify this with apt-get build-dep ruby1.8. If some packages are missing, they will be installed. After this command you should have the gcc-compiler, as well as several development-headers installed.
Extract the Ruby source archive in … let’s say /tmp/ruby-compile. Run the configure build-script and declare a prefix-directory in e.g. /opt/ruby-1.8.7 so that the path doesn’t conflict with the default Debian installation (./configure --prefix=/opt/ruby-1.8.7). After that compile Ruby with make and install it with make install. If all files were correctly installed you should be able to run Ruby 1.8.7 with /opt/ruby-1.8.7/bin/ruby.
Update your “Alternatives”
If the interpreter was installed correctly there is only one thing left to do: update the symlinks in /usr/bin/ruby to the correct Ruby version. Debian provides some scripts for this kind of tasks. There is this /etc/alternatives directory which contains symlinks to the default version of the used program. It is possible to switch the version of the installed program with update-alternatives --config <program-name>. So it is e.g. possible to install multiple versions of Java like e.g. Java 5 and Java 6 and switch between them with update-alternatives --config java.
To do this for Ruby you must first of all delete the symlinks /usr/bin/ruby, /usr/bin/irb, /usr/bin/gem, /usr/bin/rdoc, … Then you must create a new alternative with the update-alternatives script, which looks like:
update-alternatives --install /usr/bin/ruby ruby \
/opt/ruby-1.8.7/bin/ruby 100 \
--slave /usr/bin/irb irb \
/opt/ruby-1.8.7/bin/irb 100 \
--slave /usr/bin/ri ri \
/opt/ruby-1.8.7/bin/ri 100 \
--slave /usr/bin/gem gem \
/opt/ruby-1.8.7/bin/gem 100 \
--slave /usr/bin/rdoc rdoc \
/opt/ruby-1.8.7/bin/rdoc 100
Now you can switch between multiple Ruby versions with update-alternatives --config ruby. Rubygems must be installed for each ruby-version separately and gems are also maintained separately for each version. So don’t forget to install it for the 1.8.7 version when upgrading to it.
01.06.2009 18:57 | Comments (0)
Lately, I’ve been profiling one of my Merb applications with ruby-prof - an amazing profiler for the Ruby programming language. Since there doesn’t seem to be an obvious way to include the profiler into Merb so that it profiles the whole controller, model and view code I’ve come up with a small hack monkeypatch which handles this stuff.
The patch hooks into the handle-method of the Merb::Request-class and is pretty simple:
1 module Merb
2 class Request
3 alias old_handle handle
4
5 def handle(*args, &block)
6 __profile__("request", 1, 1) do
7 old_handle(*args, &block)
8 end
9 end
10 end
11 end
The __profile__-method is a nice extension of the Kernel-module provided by Merb. It creates the file “request.html” in the log-directory of your Merb-project using RubyProf’s HtmlGraphPrinter with a minimal percent of 1 (= second parameter) and it profiles the code within the block once (= third parameter).
You can put this snippet into your Merb.root/lib directory as “profile.rb” file to monkeypatch it into the Request-class. If you do so don’t forget to enable automatical loading of the lib-directory in your config/init.rb file by uncommenting the following line:
1 Merb.push_path(:lib, Merb.root / "lib")
The above snippet always overwrites your single “request.html”-file, if a new request was handled, so you might want to add a timestamp to the filename to keep older files and don’t overwrite them.
12.29.2008 18:00 | Comments (0)
Since a few weeks I’ve been managing a small ~50 client network with a Samba PDC and several Windows XP clients and roaming profiles. This network consists basically of a few computer labs with a lot of different users. Each of the users has an own e-mail account, which were configured manually, which is needles to say a pain in the ass.
My first attempt to automate the configuration was a startup-script, which doesn’t worked well. The problem was that Thunderbird is in our autostart-folder, which means each time the user logs in, Thunderbird starts immediately, loading the old configuration file. When closing Thunderbird it writes its loaded file back to disk, making potential changes via startup-scripts impossible :(. Moreover plain batch-scripts just sucks compared to advanced scripting languages like Ruby or Python.
Fortunately there is a way to autoconfigure Thunderbird via JavaScript, so that each time a user logs into the domain, he gets his own E-Mail account preconfigured.
First of all, you must configure Thunderbird to load a special configuration file on startup. To accomplish this you must modify the file all.js in C:\Program Files\Mozilla Thunderbird\greprefs\all.js. Find the following line:
pref("general.config.obscure_value", 13); // for MCD .cfg files
and change it to
pref("general.config.obscure_value", 0); // for MCD .cfg files
Normally the configuration file, we want to create, is by default ROT-13 encoded, which is, however, unnecessary and irritating and thus we are going to disable it. Then insert after this line the following line:
pref("general.config.filename", "thunderbird.cfg");
This tells Thunderbird to open the file C:\Program Files\Mozilla Thunderbird\thunderbird.cfg in which the actual configuration part happens. This file includes the following two lines:
var name = getenv("USERNAME");
pref("general.config.vendor", "thunderbird");
pref("autoadmin.global_config_url",
"http://config.thunderbird.yourdomain/configurator/show/" + name);
getenv(“USERNAME”) returns the Windows XP Username of the currently logged in user. Via the autoadmin.globalconfigurl option you can specify an url on your webserver from which thunderbird will fetch its prefs.js-file each time it starts. On the webserver you might use your favourite scripting language to generate the config dynamically for each user. In the lab network the mail-addresses are generated simply by convention, but there are a few exceptions. Thus I’ve written a small web-application which enables me to configure mailboxes for each user whose mail address isn’t conform the conventions.
To generate a skeleton prefs.js file I’d simply recommend you to create a clean Thunderbird configuration and then copy the C:\Documents and Settings\USERNAME\Application Data\Thunderbird\Profiles\SOMETHING\prefs.js file and edit the user-specific components.
The disadvantage of this method is, however, that you must update the master-image of your workstations and deploy it on your workstations to initially configure Thunderbird for fetching the configuration from the URL. Further changes can be made on your webserver.
Further details can be found under
08.24.2008 20:21 | Comments (0)
It’s actually possible to extend Vim not only with the built-in Vim-Script, but also with more popular scripting languages like Ruby or Python, which offer more features and have a better library support than Vim-Script.
Before getting started you should make sure, that you have compiled Vim with Ruby support, which should be the case on all modern Linux distributions though.
After that, might want to write a simple hello world example. So create a file hello.rb with the following contents:
1
2 def hello_world
3 Vim::Buffer.current.line = "Hello World"
4 end
5
6 Vim.command("function! HelloWorld()
7 ruby hello_world
8 endfunction"
9 )
10
11 Vim.command("map <F10> :call HelloWorld()<CR>")
This simple script replaces the current line in the buffer with “Hello World” when pressing F10. To load the script you should add “rubyf /path/to/hello.rb” to your vimrc-file.
Unfortunately it seems that there is no real documentation for the exported Vim-classes, but if you download the Vim-sources you can read the ruby-extension in the src/if_ruby.c-file, in which all exported modules, classes and methods are listed. The most common things used might be:
The following classes might be important:
There are a few more things defined in the if_ruby.c-file, so you might wanna check it out if you want to extend Vim using Ruby.
Examples of Ruby-extensions are the rubycomplete.vim script, the vimblog script, my new snip-fu project, which is currently only experimental software though and possibly many more of which I don’t know.
So if you always wanted to extend Vim but don’t like Vim-Script very much, you should look into the scripting language interfaces of Vim.
08.17.2008 13:08 | Comments (0)
Today I figured out how to integrate the OpenSource issue tracker Trac with GIT. I used to use Trac a lot for my SVN-projects, since it has a nice integrated code-browser, supports tickets with milestones, has a roadmap as well as a timeline and supports closing of tickets with SVN-commits.
Kudos to Herbert Valerio Riedel, who has coded an awesome plugin, which enables Trac to use GIT as versioning system backend. There are some caveats though. The plugin makes use of fork and the git-command, because there is no “libgit”. Thus it’s not very fast. It might be faster, if the config-files would be parsed directly with Python. Most of this issues can be solved through enabling caching, which works for me only in the SVN-version of the plugin though (which I’m currently using).
To get up and running with Trac, GIT and Debian 4.0, I’ve done the following steps:
Install Trac 0.11 with Python 2.5:
Python 2.5 can be installed via apt:
aptitude install python2.5 python2.5-dev
Debian 4.0 has no packages for Trac 0.11, which means that it must be installed via the setuptools. There is a virtual package for the setuptools for Python 2.5, but somehow it doesn’t work and installs the setuptools only for Python 2.4 :/. Thus you should download the setuptools and install them manually for Python 2.5:
wget http://peak.telecommunity.com/dist/ez_setup.py
python2.5 ./ez_setup.py
After installing the setuptools, go to http://trac.edgewall.org/ and download the newest version of Trac. Execute the setup-script via
python2.5 setup.py install
to install Trac with all required dependencies.
Install GIT 1.5.X
To run the newest version of the plugin GIT 1.5.2+ is required. The default version, which is included in Debian is 1.4.X. Fortunately, there is a more recent version in the Debian-Backports:
aptitude -t etch-backports install git
If you haven’t enabled the backports on Debian, you should follow the instructions on backports.org.
Create a fresh Trac-Project
Create a new Trac-Project via
trac-admin /path/to/repo initenv
and follow the instructions. Your repository type should be git and the path to your repo should be the path to your local git repository. If you have a “normal” repository, this is the .git-directory of your project and not the directory with your working copy. If you have a bare-git-repository, just use the normal path.
Install the Plugin
Grab a fresh SVN-checkout from GitPlugin and run:
python2.5 setup.py bdist_egg
which will create a .egg-file in the dist-directory. This .egg file should be copied into the plugins-subdirectory of your Trac-project directory.
If you now run the tracd daemon in your project-directory, you should be able to browse through your git-files and see your changes. I strongly encourage you to enable the caching-options in the trac.ini-config, as described here.
Post Commit Hooks
If you want to fix tickets using commit-messages, like with SVN you can use trac-post-commit-hooks with git. Just grab the trac-post-commit-hooks file for your Trac-version and place them somewhere on your server. Then open your hooks/post-commit-file hooks/post-receive in your git-repository on the server and add the following to it:
read x <<< `git log -1 | sed -e 's/commit//' -e '2,$d'`
python2.5 /root/bin/trac-post-commit-hook -r $x -p /path/to/trac/project
You must make sure, that your committer-user can modify the Trac project. I’m used to put my git-committers into a git-group, so I’ve chowned simply the Trac-project recursively to www-data:git and made a chmod g+w recursively on the directory.
Now you can close tickets with a commit like “improved performance. Fixes #3”.
08.09.2008 20:51 | Comments (2)
I’ve written a small update for mini-blog the last week. Now you can finally comment my entries =). Hopefully this feature works in all major browsers.
Moreover I’ve released one of my tiny “learning”-projects on GitHub: “hss” - a ncurses based feed-reader written in Haskell. The main purpose of this project was for me to get a bit into functional programming. Thus you shouldn’t use it as your “real” feed-reader, since it only supports RSS-2.0 and it lacks a lot of features you’d might expect from a feed reader.
Functional programming is actually very different from other paradigms. I guess it will take a long time until I fully grasp Haskell.
08.07.2008 00:53 | Comments (0)
Since I don’t own a Mac, I’m using VIM for text editing and not the popular TextMate editor. VIM has a steep learning curve, but once you get into it, it’s a really nice editor. The only thing missing for me was a reasonable snippet support like many IDEs and TextMate have.
Fortunately I stumbled upon the great snippetsEmu Plugin from Felix Ingram. The plugin is really great, and if you’re missing snippets in VIM too you should definitely check it out.
It’s also easy to extend using the buildin VIM scripting language. Since I’m using RSpec for testing my code, I’ve added a few snippets to my ~/.vim/after/ftplugin/rubysnippets.vim file for creating specs and matchers:
1 exec "Snippet it it '".st."description".et."'".st.et
2 exec "Snippet desc describe ".st."class".et." do
3 \<CR>".st.et."
4 \<CR>end
5 \<CR>".st.et
6 exec "Snippet matcher module ".st."matcher".et."
7 \<CR>class ".st."class".et."
8 \<CR>def initialize(expected)
9 \<CR>@expected = expected
10 \<CR>end
11 \<CR>
12 \<CR>def matches?(target)
13 \<CR>@target = target
14 \<CR>end
15 \<CR>
16 \<CR>def failure_message
17 \<CR>end
18 \<CR>end
19 \<CR>
20 \<CR>def ".st."method".et."(expected)
21 \<CR>".st."class".et.".new(expected)
22 \<CR>end
23 \<CR>end
24 \<CR>".st.et
25 exec "Snippet sh= should == ".st.et
26 exec "Snippet she should eql(".st.et.")".st.et
27 exec "Snippet stb stub!(".st.et.")".st.et
28 exec "Snippet ar and_return(".st.et.")".st.et
29 exec "Snippet sh should".st.et
30 exec "Snippet sht should be_true".st.et
31 exec "Snippet shf should be_false".st.et
32 exec "Snippet shr should_receive(".st.et.")".st.et
33 exec "Snippet shn should_not".st.et
34 exec "Snippet shm should match(".st.et.")".st.et
35 exec "Snippet shc should change(".st.et.", ".st.et.")".st.et
36 exec "Snippet shht should have_tag(".st.et.")".st.et
37 exec "Snippet befo before(:each) do<CR>".st.et."<CR>end<CR>".st.et
38 exec "Snippet afto after(:each) do<CR>".st.et."<CR>end<CR>".st.et
As you might noticed, the cursor stops at those .st.et.-marks. If there are multiple marks in one snippet, you can jump to the next mark via TAB.
The only problem which I experienced is, that after using a snippet, the standard copy-buffer is emptied, which is actually very annoying. Named buffers though are still working after using a snippet. Thus I guess I should train myself using more named buffers when copying code :).
08.04.2008 17:23 | Comments (0)
Today I’ve released my tiny Blogging Software “mini-blog”, which I’m using here, on github.
It’s a very simple software for minimalists (like me), created with the Ruby webframework Merb and the ORM DataMapper. At the moment it is only possible to manage entries and static pages using markdown. Static pages though, must by manually included in the application.html.erb file. There is at the moment no such thing as automatic inclusion of pages in the menu and so on. For the admin-sections of the blog activated JavaScript is required, since I’m using Ajax for previewing the markdown-text and for deleting things.
Feel free to use it, fork and extend it, ignore it or whatsoever :).