Sun 04 November, 2007

add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
Tip Class Variables
In his RubyConf 2007 Keynote presentation Matz stated that, as a general rule, you should not use class variables.
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
“ The suits people are surrounding us. ”
Matz, on Ruby becoming “Enterprisey”
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furlFri 02 November, 2007

“ Models are perfectly beautiful, but without sufficient training make terrible neurosurgeons. ”
Marcel on Beauty
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furlThu 01 November, 2007

JRuby语言内部报道:Rails框架版本1.2.5在JRuby版本1.0.1版本以下兼容错误
- JRuby错误报告
http://jira.codehaus.org/browse/JRUBY-1401 - JRuby错误信息
“...lib/ruby/1.8/pathname.rb:420:in `realpath_rec': No such file or directory...” - 错误原因
在Windows系统下没有处理好驱动器名称。这个也是软件开发的常见错误。 - 说明:
这个问题将在JRuby版本1.0.2被解决。JRuby版本1.0.2已经发行。
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl

I have just aborted a week-long oddisey of finding a good mail client that can deal with pretty big IMAP mail boxes. (Of course, this is because Gmail now does IMAP, which is a really nice idea.)
They all suck, are too slow, or both.
Before everyone now comes shouting, “Bah, just use Mail.app”, these are my requirements for this use case (I’ll try Mail.app again as soon as I get Leopard, and will tell you how it breaks down then…):
- Must work over SSH without X, which means console/line based
- Must support IMAP well (bye mutt)
- Must support big mailboxes (100k messages and more)
- Must be open-source
- Should be unixish in some way
One more word about the big mailboxes: I do not need to see all headers at all times, and if the mailer can operate fast on a subset (say, the last 2000 mails), this is fine enough. I’d rather use a quick program with a smaller working set than a slow program which shows all messages of this century. In fact, this is recommended by the IMAP client coding HOWTO. (I think only Pine does it, and that didn’t work too well either.)
I tried all of these: Mutt (the only program with nicer source than interface), Pine (works well with smallish IMAP boxes, but breaks down with my 172k-ruby-talk box), Nail (same, and the UI sucks), and Cone (I gave up compiling).
As you will notice, most of these clients are written in C. It’s probably because of their age, but really it is a waste of time. Mailers written in C are the worst you can imagine, except for mailers written in C++, which share the issues but take ten times as long to compile.
Mail clients written in C usually means that they are noncustomizable/untweakable (Pine) or they use hacky configuration language (Mutt). Scripting languages exist, and given proper algorithms and datastructures (which you need anyway, if you want to make a scalable mail reader), they are fast enough to do anything mail related, while still being proper, portable languages for extensions and plugins. (There are a few mail programs written in Perl, but they don’t seem successful.)
I’m back to Gnus/fetchmail/Maildir now. It can support IMAP, and works relatively fast (see below for reason), but searching for new mail is slow, and blocks my complete Emacs (I may end up just starting two instances…).
And Gnus, I now realize, is a fine mail reader. This probably is because it was made as a news reader, and the virtues of a news reader are what counts in my case: Gnus asks you how many messages to load (usually just the unread ones), and works zippy with them then, but even with 10k of messages, it still *is* usable.
Furthermore, it has a seriously cool feature: expiring. You don’t delete mail (I never do that, anyway, which is why my mailboxes are getting so big), but you expire it, and if the mail is expired and older than a week or so (configurable), it either deletes it, or moves it into a different mail box, or does anything you tell it with elisp. I now use this to make monthly mbox-archives of ruby-core and ruby-talk, since HFS+ doesn’t really like 150k+ files in a directory.
Which gets me to a side note… one of my first posts on this blog was about mail storage formats, and Maildir essentially was the winner. Maildir is rock-solid, but tools like rsync or rsnapshot really have to work hard to back them up, if they reach a decent size. And many file systems (still no ZFS in OS X) slow down a lot. I’d like to propose a Multimaildir format that stores mails like Git in Maildir/000/999 and the next one in Maildir/001/000 instead of stuffing them all into one directory. Should be pretty easy to do, and makes everything faster. (You also could move your old mail easily, just move Maildir/000 somewhere else (O(1)), instead of globbing like hell (O(n)).) End of sidenote.
I also had a closer look at MH, which always fascinated me. There is a good O’Reilly book on it available online, and I like how it was designed. Very unixish. I can’t really imagine using it, though. (I read/skim lots of mailing lists, and apparently MH doesn’t thread, and I guess it’s just too slow to vgrep a summary and read the few interesting posts. Maybe with a really well-tuned Zsh setup, with keybindings and everything.)
For half a day I glimpsed the idea of writing an IMAP-based MH. In fact, such a thing, written in Python, exists as MHI. But I’m not sure I really want to use it, and it would suck to spend a lot of time to reinvent the wheel and not even drive with it.
So, I thought about my needs, did a bit of research with antique mail clients. (Did you know jwz used Netscape 3.02 for a looong time to read his mail? Not console based, unfortunately.)
Now, I’m sucking it down and will write my own client, and I’ll use something one rarely sees on Unix: lets call them “interactive non-screen based interfaces”. Actually, that’s wrong, because you probably use the shell every day. Mutt and Pine take all your screen and are nontrivial to implement (you need to do a pager, and all the curses stuff, yeech), while mail/mailx/nail are totally-line based and you need to end each command by pressing return (which is one key too many for lots of mails).
I think we should do it like this: make a small library that provides a few widgets, like “line picker”, “item picker”, “line reader”, add an Emacs-style (or, almost easier, vi-style) keyboard map system to dispatch between these and make all input interactive (cbreak). Many apps on ITS worked like that, and it’s pretty comfortable to use, while still fast, flexible and text-based.
I’m pondering making a Gnus feelalike in Ruby based on this scheme, with the following very limited function set: just IMAP (but that well), and all configuration by editing/adding Ruby, threading like jwz does it, and just the stuff I need. One should have usable results within a week, who knows.
I could end up in the history of men by writing the first mail reader that doesn’t suck. :-P
NP: Bob Dylan—No More Auction Block
add to del.icio.us. look up in del.icio.us.
add to furlWed 31 October, 2007

“ I spend most of my life in anticipatory nostalgia, aware of the memories I’m creating. ”
Sam Reich’s dad
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
Unless I’ve sold it by the time you read this, I have an extra ticket for RubyConf 2007. (Not mine; I’m still going!)
Price: $250. That’s the face value for the full-meal ticket.
<strike>Drop a line to james.britt@gmail.com if you are interested.</strike>UPDATE: The ticket has been sold.
add to del.icio.us. look up in del.icio.us.
add to furl
people.collect(&:name)
这段代码实际上等价于
people.collect { |p| p.name }
但是,从Ruby的语法上来看,这行代码看上去是很难理解的,主要就是&:name。把这行代码当作Ruby脚本直接运行,你会发现,Ruby会向你报错,错误是:
wrong argument type Symbol (expected Proc) (TypeError)
那么为什么这样的代码遍布于Rails,却能正常运行呢?
最初困扰人的可能主要是&:name的写法,这看上去根本不像正常的Ruby语法,但只要将它进行适当的分解,我们就豁然开朗了。在Ruby中,“&”通常用来表示后面跟的是Proc,而:name在Ruby中表示一个Symbol。把二者结合在一起,矛盾变产生了,”&”要的是一个Proc,而我们给的一个Symbol,这就是前面错误的来源。
知道了错误的来源,接下来的问题是,Rails里究竟变了怎样的魔术,让这段代码通过呢?
其实,“&”后面如果跟的不是一个Proc,那么它会试图找寻一个Proc,在Ruby中,这意味着它会调用to_proc方法。这是Ruby中的一种标准协议,关于这种转换协议,可以参考《Programming Ruby》中《Duck Typing》一章相关的介绍。
由于后面的是一个Symbol,结合前面的说法,只要为Symbol类提供一个to_proc方法,至少在语言层面上,就会变得正确起来。事实上,Rails正是这样做的。
class Symbol
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end
(activesupport/lib/active_support/core_ext/symbol.rb)
如果说to_proc仅仅是让这个魔术在语言层面上通过,那么上面这段代码也解开了其余部分的神秘面纱。不妨再进一步,看看它究竟是如何做到的。
通过开始的代码等价对比,我们已经知道了这行的代码意义,主要也就是调用了一个对象的方法。将它对应到Proc.new所附带的block上,我们便不难看出这段代码的意义所在了。
这里的*args是block的参数,在前面的例子中,p就是这个参数,我们要调用p的name方法,所以,p是作为receiver的,而args.shift正是将p提取了出来。通过__send__,我们就可以调用receiver的方法,而__send__需要一个Symbol指定要调用的方法,别忘了,我们正是在一个Symbol类中定义方法,于是self成为了一个自然的选择。至于剩余的参数(对*args调用shift之后),就作为参数传给方法了。实际上,大多数用法中,只有一个参数,所以,剩余的部分会是一个空数组。
通过这种变换,p.name就等价于args.shift.__send__(self, *args)了。
关于这段代码的实现,也许Ruby Extensions的实现更加清楚一些。
def to_proc
proc {|obj, *args| obj.send(self, *args) }
end
这段代码将receiver分拆出来,所以,更加容易理解。当然,严格的说,二者还是稍有差别,这种实现必须要有一个参数。但是,在大多数情况下,这种实现已经足够了。
add to del.icio.us. look up in del.icio.us.
add to furl
Paris on Rails is a French-speaking Rails conference that’s taking place in Paris on December 10th. They have a great program for the day with 10 speakers (yours truly included via a video chat). If you speak French, check it out. The one-day event is 100 euro (or 70 euros before November 15th).
add to del.icio.us. look up in del.icio.us.
add to furl
RailsConf 2008 is set to return to Portland on May 29th through June 1st. It takes a lot of time and coordination to get a conference of that magnitude put together, so we’re starting early by asking for presentation proposals from the community. The submission deadline is December 13th.
We’re really hoping to get some more advanced stuff this year. More nitty gritty details. More code on the wall. What did you learn from your last project that others could benefit from too? What techniques have you been experimenting with? What awesome plugins do you find invaluable? This is the place to share all that learning with the rest of the community.
A good reason to take that bold step into submitting a conference proposal is to raise your visibility in the community. I’ve met with lots of speakers who say that they got great business leads after presenting at a Rails conference. Your next client, boss, co-worker, or open-source collaborator may well be in the audience when you’re presenting.
Most of all, though, it’s a lot of fun to share and you tend to learn as least as much as your audience when giving a presentation at a major conference like this. I strongly recommend that you think about which areas of Ruby on Rails you’re especially passionate about and submit a proposal to share that passion.
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furlTue 30 October, 2007

“ In Japan, we have tradition to value cute things high. ”
Yukihiro Matsumoto
add to del.icio.us. look up in del.icio.us.
add to furl
2. Electricity Of or relating to two oscillating circuits having the same resonant frequency.
add to del.icio.us. look up in del.icio.us.
add to furlMon 29 October, 2007

2. The amount by which a container, such as a bottle, cask, or tank, falls short of being full.
add to del.icio.us. look up in del.icio.us.
add to furl