Friday, December 17, 2010

Shell escaped file names in ruby

When files have crazy characters in their filename (like ' or ""), it can make creating a robust script challenging. After all, if you write the script with either a single quotation mark or a double quotation mark, the other one will trip you up:

file1 = "my'crazy'file.txt"
file2 = 'my"crazy"file.txt'
system "mv \"#{file2}\" bettername.txt"  # fails on file2
system "mv '#{file2}' bettername.txt"    # fails on file1

The answer is to use the multiple arguments invocation, which will properly escape your filename to be fully shell compatible:

system "mv", file1, "bettername.txt"  # works on file1 or file2

Thursday, December 9, 2010

Playing with (compiling) the redesigned NArray

Masahiro Tanaka has been redesigning NArray. Word is that it may be pulled into mainline ruby.

So, what is it like? Amazing from what I can tell. How do you play with it? At least on Ubuntu 10.10, this is what I did (there may be other dependencies I've neglected here):

sudo apt-get install libatlas-dev libatlas-base-dev
# modify extconf.rb:
have_header("atlas/cblas.h")   ===>   have_header("cblas.h")
# modify linalg.c
#include <atlas/cblas.h>   ===>   #include <cblas.h>
# for ruby 1.9, you also need to change a few normal array things:

diff -r ../narray-new-1.8/narray.c ./narray.c
<     n = RARRAY(idxargs)->len;
<     ptr = RARRAY(idxargs)->ptr;
>     n = RARRAY_LEN(idxargs);
>     ptr = RARRAY_PTR(idxargs);
< const static size_t zero=0;
> //const static size_t zero=0;
> static const size_t zero=0;
<      ndim = RARRAY(v)->len;
>      ndim = RARRAY_LEN(v);
>     VALUE *ptr;
<  RARRAY(v)->ptr[i] = SIZE2NUM(na->shape[c]);
<  RARRAY(v)->len++;
>  RARRAY_PTR(v)[i] = SIZE2NUM(na->shape[c]);
>  ptr = RARRAY_LEN(v);
>     ptr++;
diff -r ../narray-new-1.8/nstruct.c ./nstruct.c
<      ndim = RARRAY(argv[i])->len;
>      ndim = RARRAY_LEN(argv[i]);

now, you should be able to "ruby extconf.rb", "make", and then require 'narray' or require './'