August 2009 Archives

台北市的咖啡店

| No Comments | No TrackBacks

IMG_4126.JPG (In Index)

台北市的店頭,與其說是沉澱心靈的場所,不如說是充分攪拌、使其更加混濁的地方。你到這些地方讓事情用力地發生,沉澱什麼的等回家洗澡時再說。

Perl in Ruby on Rails projects

| No Comments | No TrackBacks

Perl programs are powerful workers that works well especially good for data conversion tasks. One of my $client_project requires importing a big data set that’s available in either Access DB file or in CSV files. I thought: maybe a perl program can solve this quickly.

And the reason for that is of course, the almighty CPAN.

The approach to the solution is quite simple:

  • some program converts the data set into yaml files
  • write a script/runner -based Rails script to load those yaml files, and then create records with ActiveRecord, or alternatively, loading those yaml files as fixtures.

Thanks to the fact that YAML is in Ruby core library.

I found that Text::CSV::Slurp is very handy, especially when CSV field values contains newlines.

This approach has been working for two of my $client_projects and I still feel happy and confidence with it. One only needs to do one data import, the other needs to do it in a daily bases (to adapt legacy system output) and it’s up and running smoothly.

It’s not that it’s impossible to be done with Ruby, but it can be very easily done with Perl. Plus perl is built-in on the Linux server, and I happened to be very familiar with the Perl language - I see no reason that I must do it with only Ruby.

PerlX - Perl Extension

| No Comments | No TrackBacks

I decided to release this hack as a stand-alone perl module called PerlX::MethodCallWithBlock.

I was thinking putting it under Syntax::* namespace but that feels rather boring-ish. Since recently there are CatalystX, MooseX, JiftyX for naming “The extension of $foo”, I guess it’s time to have PerlX as the namespace for those modules that extends Perl itself.

Funny about the minus sign

| 2 Comments | No TrackBacks

I just discovered that there something funny about this minus sign. See if you can guess the output of the following code without running it:

use strict;
use 5.010;
$, = " ";
for my $v (qw(42 FortyTwo)) {
    say -$v, -"$v", -("$v");
    say -(-($v)) , -(-$v), -(-$v);
    say -(-("$v")) , -(-"$v"), -(-$v);
    say -(-(-("$v"))) , -(-(-"$v")) , -(-(-$v));
}

It’s pretty easy when the $v is 42, but not quite obvious when it is "FortyTwo". I don’t have any explain on it. That’s maybe documented somewhere and I’ll have to find it.

Quick notes when hacking for compile time

| No Comments | No TrackBacks

Following my previous post (Running in the compile time), it’ll be very helpful if you know what’s going to try next when it doesn’t work as expected.

Here are some notes that I concluded and found to be helpful:

  • import is executed in compile time
  • perl -MO=Deparse is your friend
  • perl -MO=Concise too
  • Devel::Declare::toke_skipspace helps peaking the next line of code
  • lineseq op gives you a chance to see every lines of code when it is compiling
  • Search ~flora for goodies

Running in the compile time

| No Comments | No TrackBacks

Yesterday I made this snippet runnable in Perl5:

Foo->bar(42) {
    say "fubar";
};

The {} bare-block there is the last argument to the invoked bar. In this case, the method bar receives 3 parameters: the context (Foo class), the 42, and a code ref.

Since this is basically pretty rubyish, I made it into Rubyish in this commit.

If you’re interested in how to make it possible, read on.

Hash::Lazy

| No Comments | No TrackBacks

Just shipped Hash::Lazy, a spiffy way to let you build a hash lazily.

| perl -0777 -pe 's/xxx/yyy/g'

| No Comments | No TrackBacks

這是一條常用的單行程式,其作用是:讀取 STDIN,把其中 xxx 出現的地方全部都換成 yyy,然後印出來。

其中的 -0777 這個參數很有意思,它表示:讀 STDIN 時一次全部讀完。這是一個短線字符,後面跟著四個數字:零、七、七、七(而不是英文字母的 O。)

Perl 語言有個讀取 IO handle 用的運算符寫成 <>,叫做「鑽石運算符」。預設會一次讀取一行資料進來:

my $line_1 = <>; # 第一行
my $line_2 = <>; # 第二行
my $line_3 = <>; # 第三行

不過如果改了 $/ 變數的值,就可以改變每次讀取的單位。此變數預設的值是 \n,既換行字符。<> 的行為基本上是「從目前的位置開始讀,一直讀到把下個 $/ 讀進來為止」這樣的感覺。也就是說,如果有段資料 (假設存在 test.txt)是這樣:

My uncle was the town drunk -- and we lived in Chicago.
            -- George Gobel

我們可以把 $/ 改成 “—” 試試(假設這段程式存在 test.pl):

use 5.010;

$/ = "--";

my $line_1 = <>;
my $line_2 = <>;
my $line_3 = <>;

say "[$line_1]";
say "[$line_2]";
say "[$line_3]";

執行 cat test.txt | perl test.pl 會得到:

[   My uncle was the town drunk --]
[ and we lived in Chicago.
                --]
[ George Gobel
]

可知資料依 "--" 的出現而分成三段了。

如果做了 $/ = undef 的話,則是讓 <> 一次吃進所有資料。而命令列參數上的 -0777 就有等同於 $/ = undef 的效果。

這部份的原因,引述自 perlrun 這份文件 (perldoc perlrun):

-0[octal/hexadecimal]

specifies the input record separator ($/ ) as an octal or hexadecimal number. If there are no digits, the null character is the separator. Other switches may precede or follow the digits. For example, if you have a version of find which can print filenames terminated by the null character, you can say this:

find . -name '*.orig' -print0 | perl -n0e unlink

The special value 00 will cause Perl to slurp files in paragraph mode. The value 0777 will cause Perl to slurp files whole because there is no legal byte with that value.

If you want to specify any Unicode character, use the hexadecimal format: -0xHHH…, where the H are valid hexadecimal digits. (This means that you cannot use the -x with a directory name that consists of hexadecimal digits.)

Remove unwanted Jifty javascript files

| No Comments | No TrackBacks

Many Jifty frontend functionality are provided by javascript, like time picker, calendar picker, etc. It is a big load if they ended up not being used. You can provide a start method in MyApp.pm to override the default javascript. However, some of them are always required (like jQuery). I figured that this might be the minimum:

package MyApp;

sub start {
    Jifty->web->javascript_libs([qw[
        jquery-1.2.6.js
        jquery.jgrowl.js
        behaviour.js
        jquery.timepickr.js
        jifty.js
        jifty_utils.js
        jifty_subs.js
        jifty_smoothscroll.js
        app.js
    ]]);
}

Hmm, maybe it’s time to upgrade jQuery to 1.3.2 for Jifty.

Customize Jifty Page Layout

| 2 Comments | No TrackBacks

I found myself repeating this whenever I started to put styles to my new Jifty app. Maybe it’s necessary to make it easier. Actually not hard, but neither it is a trivial task.

To do this, you’ll need to do these two steps:

  1. Write a MyApp::View::Page class
  2. Modify etc/config.yml to enable it

Extend any classes

| 4 Comments | No TrackBacks

It may or may not be a good practice / group culture to do this, but it’s easy to extend any classes by manipulating the symbol table.

抓圖指令很容易,如下:

Install perl to $HOME

| 3 Comments | No TrackBacks

Since Perl 5.10.1 RC1 is out, it’s time to build my new shiny Perl!

I installed perl inside my $HOME directory ( /Users/gugod ), and here’s the way to do it:

cd ~/src; tar xzf perl-5.10.1-RC1.tar.gz
cd perl-5.10.1-RC1 
perl Configure -de -Dprefix=${HOME}/local
make
make test
make install

The -Dprefix=${HOME}/local makes it install to ~/local. Then you’ll find the perl executable at ~/local/bin/perl. Therefore I also add ~/local/bin to my PATH:

export PATH=${HOME}/local/bin:${PATH}

Why am I doing that ? Mostly because that it doesn’t require “sudo” when installing cpan modules with cpan or cpanp command. Therefore, if I need to move my $HOME to another machine (eg, when I buy a new Mac), it’s much more easier - I’ll just have to rsync my ~/local.

It’s also useful when it’s too much trouble upgrading system perl, or when you don’t really want to upgrade system perl, but want to play with those shiny Perl 5.10 features.

Update: chas.owens pointed out that one of the Cwd test will fail if the perl is building in /tmp, because /tmp is really /private/tmp on OSX. I modified this post to use ~/src as my building path.

Movable Type Cutline Theme

| No Comments | No TrackBacks

因為簡潔所以換了。請參考這裡

無題

| No Comments | No TrackBacks

歷史七八年;舊衣服二十件丟棄;勃肯鞋送修;兩星期六本;日英小說四千頁;無筆記閱讀。

持續性產出是確認自身;但以他人之回應為依賴,持續性閱讀是確認他人;但以自身之理解為回歸。

pubsubhubbub, google wave, reversehttp, ptth/0.9, webhook.

JAPH, part 2.

| No Comments | No TrackBacks

Based on previous JAPH post, I figured that I can really do it this way:

#!/usr/bin/env perl -l

*Just::AUTOLOAD = *Perl::AUTOLOAD = sub {
    $AUTOLOAD =~ /.*::(.+?)$/;
    join ' ', $_[0], $1, $_[1];
};

print Another Just Hacker Perl;

Enjoy.

JAPH

| 1 Comment | 1 TrackBack

Here’s a (sort of) JAPH code that just came up to me:

> perl -MO=Deparse -e 'Another Just Hacker Perl'
'Just'->Another('Perl'->Hacker);
-e syntax OK

It’s funny that 4 words are de-parsed into some autobox-ish form.

The Rubyish "self"

| No Comments | No TrackBacks

More about Rubyish.pm today.