Fri 19 October, 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
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
Rails core
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 furlThu 18 October, 2007

Speaking of fuck, researchers find it to boost morale at work:
Regular swearing at work can help boost team spirit among staff, allowing them to express better their feelings as well as develop social relationships, according to a study by researchers.
"We hope that this study will serve not only to acknowledge the part that swearing plays in our work and our lives, but also to indicate that leaders sometimes need to 'think differently' and be open to intriguing ideas."
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 Stop mds from taking up all your CPU
If your Spotlight index has become corrupted (somehow), the mds process which manages it will aimlessly chew up most of your CPU indefinitely.
You can stop it from doing so by clearing your Spotlight index and allowing it to rebuild at its leisure with the following command:sudo mdutil -E /
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
IntelliJ IDEA has long been regarded as one of the best IDEs for Java development. With the 7.0 release they’ve followed Netbeans and Eclipse by offering significant support for Ruby on Rails alongside the Java tooling. They have a neat video tutorial showing off the Rails features.
add to del.icio.us. look up in del.icio.us.
add to furlWed 17 October, 2007

I got sick of the page being so slow, so I this morning I made some fairly destructive slash-and-burn style changes under the hood. Things should be mostly working again, with the following exceptions:
- Themes: They're busted until I get a chance to patch them up. I have no idea what will happen if you try and use them, but probably nothing good (for you, not me).
- New Accounts: You can wait a day or so to harass me about my latest inflammatory post. Or send an email instead.
- Screenshots: Yeah my desktop from 1998 has a lower resolution than your cell phone. So what?
There may also be other stuff broken, too. I've tried to keep URLs for articles and whatnot the same, but your mileage mamy vary. Today is the first of several iterations away from the almost decade-old code this site is running.
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
Ever tried to read and write cookies in Javascript? If you have, then I'll wait until you've stopped frothing at the mouth and pounding your keyboard.
...
Feeling better? Good. I just released the first public version of EasyCookie, a simple cookie library for Javascript. Using EasyCookie is, well, easy. For example, here's how you get a cookie:
// get a cookie
val = EasyCookie.get('my_cookie');
And here's how you set one:
// set a cookie
val = 'a random value that i want to save as a cookie';
EasyCookie.set('my_cookie', val);
And, if you haven't already guessed, here's how your remove a cookie:
// remove a cookie
EasyCookie.remove('my_cookie');
But what about all the extra crap you usually have to fight to get
working, like the domain, path, and expiration? Don't panic!
EasyCookie.set takes a hash of additional attributes as an optional
third argument. Here's another example of EasyCookie.set, this time
with the optional hash:
// value to set
val = '99 bottles of beer on the wall, 99 bottles of beer!';
// set a cookie that expires in 10 days, and limit the scope to
// "https://foo.example.com/some/path"
EasyCookie.set('my_cookie', val, {
// expires in 10 days
expires: 10,
// limit cookie to domain 'foo.example.com'
domain: 'foo.example.com',
// limit cookie to path '/some/path'
path: '/some/path',
// restrict cookie to secure pages only
secure: true
});
Checking to see if cookies are enabled just got a whole lot simpler, too:
// are cookies enabled?
enabled = EasyCookie.enabled;
// harass user with annoying dialog about their cookie status
alert('Cookies are ' + (enabled ? 'enabled' : 'not enabled'));
Best of all, EasyCookie is BSD licensed, and the minified version weighs in at a measly 1873 bytes. Anyway, here ya go:
PS. Yes, I realize the link above are to version 0.2.1 of EasyCookie, even though this is the first public release. In internet years the backend to my page is older than your grandmother. Imagine trying to explain how to release software to your grandmother.
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
Last night was bowling night. (164, 174, 129, in case you were wondering.) Thomas (my 9 year-old) goes with us and hangs out with us or in the arcade. Last night, his best friend went too, because his best friend's mother was also bowling. So there we were at the bowling alley, having a good time.
Shortly before we were going to head home, Thomas and his best friend were running around (politely) and pretending to have some sort of ninja battle or Power Ranger fight or some other struggle against the powers of evil that kids do. The following dialog then ensued:
Me: Hey guys... this isn't Fight Club, you know?I laughed my head off.
Thomas: The first rule of Fight Club is you don't talk about Fight Club!
Me: ...
And no, he hasn't seen Fight Club. We were watching some kids show recently, some cartoon, and there was a bit of dialog something like "... the first rule of Fluffy Bunny Club is you don't talk about Fluffy Bunny Club..." or something like that. I immediately cracked up, and so I had to explain to him why that was funny. I told him about that one scene in Fight Club and he obviously remembered it very well. Too well. I'm sure the other adults who were nearby now think I let him watch inappropriate films...
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 16 October, 2007

2. Biology Fleeting; lasting a short time; applied particularly to organs or parts which are short-lived as compared with the life of the individual.
add to del.icio.us. look up in del.icio.us.
add to furl
Reddit updated their site layout yesterday, which broke my Reddit Content Filter Greasemonkey script. I just posted a new version a few minutes ago, along with my Reddit Navigational Access Keys script, which I apparently never posted to User Scripts.
I've also hosted both files here:
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 furlMon 15 October, 2007

2. The use of a strained figure of speech, such as a mixed metaphor.
add to del.icio.us. look up in del.icio.us.
add to furl
I've been using the migration and some recent side projects as sandboxes to try out new things. Here's a semi-random list of useful tidbits I've picked up along the way:
Better mod_rewrite magic: Google turns up plenty of mod_rewrite examples on automatically stripping the dreaded "www." prefix from URLs. Unfortunately, most of them appear to be incorrect. Here's the most common solution:
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]What it's supposed to do is redirect visitors from
http://www.example.com/whatevertohttp://example.com/whatever, but what it actually does is redirect visitors tohttp://example.com//whatever. It's minor, but it was driving me nuts (Arrrrrrr). Anyway, here is the correct solution:RewriteCond %{HTTP_HOST} ^www\. [NC] RewriteRule ^/(.*)$ http://example.com/$1 [R=301,L]mod_deflate: Saves a ton of bandwidth, works great in IE7 and Firefox. The stock settings don't include a couple of common MIME types; here's the list I'm using: text/html text/plain text/xml text/css text/javascript application/x-javascript text/csv
- XCache: Fast PHP opcode cacher that actually works with recent versions of PHP. I tested several Wordpress, Gallery, and custom PHP sites without incident, and my (incredibly rough) benchmarks showed about a 4-7% increase in mean transfer speed.
ExtJS Builder: I decided to test the ExtJS builder for a personal project. The interface is a bit finicky; it took me about 5 tries to get all the dependencies for my project selected. Here are the results:
File Minified Deflated ext-all.js 468k 125k ext-mine.js 276k 77k Note: The "Minified" column is the total file size after being shrunk with Douglas Crockford's excellent
jsmin, and the "Deflated" column is the actual transfer size (according to Firebug) after being passed throughmod_deflate.Not too shabby for 20 minutes of work. I'm a little bit disappointed by the stock mod_deflate compression ratio, so that may need a bit of tweaking.
Backgrounding Mercurial Hooks: The Mercurial book has an excellent chapter on hooks. What it doesn't mention, unfortunately, is how to run hooks in the background. I have a semi-lengthy
outgoinghook (roughly equivalent to a client-sidepost-commitfor you Subversion weenies) that connects to a web server viasshand performs some deployment tasks, and all attempts at backgrounding a shell script eluded me. Well, it turns out Mercurial has an extra hidden file descriptor that has to be closed in order to background a hook. So here's my down and dirty client-side background deployment hook:# # outgoing hook script that connects to web server and deploys # the latest site from tip. It is run in the background after a # successful 'hg push'. # # options opt = { # remote hostname 'host' => 'web', # remote command (relative to my home directory) 'cmd' => 'bin/update_site.sh', # client-side log (set to /dev/null to disable) # 'log' => '/dev/null', 'log' => '/tmp/site_update.log', # delay (in seconds) before update 'delay' => 3, } # fork and run update in background pid = fork { # close stdin, stdout, and stderr $stdin = $stdin.reopen('/dev/null', 'r') $stdout = $stdout.reopen(opt['log'], 'a') $stderr = $stderr.reopen(opt['log'], 'a') $defout = $stdout # close all other file descriptors # NOTE: mercurial appears to have a hidden fd laying # around somewhere, so this evil is necessary... (3..99).each { |fd| IO.new(fd).close rescue nil } # wait for push to finish # (this should poll the hg server instead, to handle # lengthy pushes) sleep opt['delay'] # run update command and exit args = ['ssh', opt['host'], opt['cmd']] exec(*args) # never reached exit 0 } # reap child and exit flags = Process::WNOHANG | Process::WUNTRACED Process.waitpid(pid, flags)
Update: Markdown really mangled my markup this time around. Usually it's pretty tolerant, but apparently this post was just a bit too much. Oh well...
add to del.icio.us. look up in del.icio.us.
add to furl
I've spent some time sifting through the documentation for LLVM, and I'm both impressed and horrified. I'm not sure I've ever seen so much documentation about something that looks really cool that I'm not interested in. I've been reading the dragon book and Advanced Compiler Design and Implementation, and I wanted to use LLVM to generate a simple runtime JIT compiler, but I can't seem to find the necessary documentation.
I see plenty of documentation on the IR, the various command-line tools, and just about everything else LLVM-related except for a straightforward tutorial that explains how to
- blast either opcodes or IR at the LLVM API, and
- have LLVM either emit an ELF/blob/whatever or execute the result.
I did manage to find a couple of examples that give me half of what I want. The source code ships with a sample Brainfuck compiler which reads an input bf file and emits LLVM IR. There are a couple more examples that show how to construct a basic JIT, then create some functions that do frustratingly simple things like calculate Fibonacci numbers or add two integers together, but nothing that's too much more detailed than that.
Oh, did I mention that the online API documentation is broken?
A bit of googling turned up libjit, which is almost exactly what I want. It's got a simple C API (instead of the nightmarishly bloated C++ monstrosity that is the LLVM API), a simple build and link system, and simple, straightforward and complete documentation. In short, it's everything that I want.
It's also GPL-licensed, which makes it almost completely unusable. I found this 2006 email exchange comparing libgit and LLVM. The author, who apparently works on libgcj, mentions all of my problems with LLVM (sans the anti-C++ bias).
My other crazy idea was to generate C as an IR and blast it at libtcc, but with my limited fiddling I couldn't get to do anything other than segfault on me. Incidentally, the documentation for libtcc is a single file and it's still better than what's available for LLVM.
So here's my question: Is there a decent book or tutorial that walks through the LLVM API? I've Googled to the end of the earth and back, I've seen the Stacker documentation, and I've read through everything in the LLVM documentation section, and none of it was what I'm looking for. I'm open to suggestions...
add to del.icio.us. look up in del.icio.us.
add to furl
Project Honey Pot is a DNSRBL to preemptively block comment spammers, harvesters, and other nefarious types on the web. This afternoon I tested 50ish "spammy" IP addresses that Akismet missed and Honey Pot caught about 10% of them. Unfortunately, I don't have a good balanced corpus of comment spam to do a full comparison between the two, so I'll be using both together for the time being.
Anyway, I've been sitting on mostly complete Ruby Honeypot bindings for a while, but this evening I whipped up some PHP bindings too.
Note that you'll need to create a Project Honey Pot account to get an API key (but don't worry, it's free). Without any further ado:
# sample API key
$api_key = 'asdf1234asdf';
# ip/hostname to check
# (this will almost always be $_SERVER['REMOTE_ADDR'])
$addr = '127.1.10.1';
# create new honeypot instance
$honeypot = new Honeypot($api_key);
# check address
if ($honeypot->is_ok($addr))
echo 'address is okay';
else
echo 'address is NOT OKAY';
You can override the default age and threat thesholds by passing additional arguments to the constructor, like this:
$honeypot = new Honeypot($api_key, array(
'ok_age' => 300, # set age threshold to 300 days
'ok_threat' => 50, # set threat level threshold to 50
));
Using the check() method instead of is_ok() gives you more detailed
results. Say you're only concerned about fairly recent harvesters, and
not comment spammers or anything else:
# check the address
$result = $honeypot->check($addr);
# check for recent harvester results with a high threat level
if ($result && $result['is_harvester'] &&
$result['age'] < 30 && $result['threat'] > 128) {
echo 'address is NOT OKAY';
} else {
echo 'address is okay';
}
Files:
- Download Honeypot-PHP 0.1.0 (Signature)
- Honeypot-PHP 0.1.0 PEAR Package (Signature)
- Honeypot-PHP Mercurial Repository
If you're using Wordpress, someone else already wrote a handy http:BL Wordpress plugin. I didn't see a decent generic Honeypot l ibrary, which is why I wrote this one.
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
软件命令解说:Windows XP系统有用的十个命令
- 查看你环境变量信息
set | findstr .HOME - 查看你系统进程
tasklist /SVC - 停止你系统进程,如进程号12345
taskkill 12345 - 启动你的系统服务,如名称名称MyService
sc start MyService - 打开你的控制面板
control - 构造你自己的字符
eudcedit - 了解你的计算机信息
systeminfo | more - 了解一个目录所有信息
tree c:/temp - 获取计算机网络地址信息
ipconfig - 打开你计算机器
cacl
add to del.icio.us. look up in del.icio.us.
add to furl
After a much larger delay than I would have liked, Capistrano 2.1 is now available! (Capistrano is a utility for executing commands on multiple remote machines in parallel, and is the tool of choice for many Rails developers for automating deployment.) There is a lot going on in this release, including some pretty exciting changes. As ever, install it via RubyGems with:
gem install capistrano
Here’s what’s new, roughly in order of magnitude:
No default PTY. Prior to 2.1, Capistrano would request a pseudo-tty for each command that it executed. This had the side-effect of causing the profile scripts for the user to not be loaded. Well, no more! As of 2.1, Capistrano no longer requests a pty on each command, which means your .profile (or .bashrc, or whatever) will be properly loaded on each command! Note, however, that some have reported on some systems, when a pty is not allocated, some commands will go into non-interactive mode automatically. If you’re not seeing commands prompt like they used to, like svn or passwd, you can return to the previous behavior by adding the following line to your capfile:
default_run_options[:pty] = true
Disable sh wrapping. Some shared hosts do not allow the POSIX shell to be used to execute arbitrary commands, which is what Capistrano has done since 2.0. If you’re on such a host, you can add the following line to your capfile:
default_run_options[:shell] = false
Capistrano will then run the command directly, rather than wrapping it in an “sh -c” command. Note, though, that this means that your own user shell on the remote hosts must be POSIX compatible, or you’ll get cryptic errors.
Git SCM support. Many thanks to Garry Dolley, Geoffrey Grosenbach, and Scott Chacon for their work on the new Git SCM module for Capistrano. If you’re a user of Git, you can now do:
set :scm, :git
Accurev SCM support. Thanks to Doug Barth, all you Accurev users can now enjoy Capistrano, too. Just do:
set :scm, :accurev
Rails’ Plugin Support. Capfile’s generated via the “capify” utility will now include a line that will autoload all recipes from vendor/plugins/*/recipes/*.rb. If you want this feature and you’ve already got a Capfile (and you don’t mind losing any changes you might have made to your Capfile), you can delete the Capfile and re-run “capify .”. Or, you can just add the following line to your Capfile, before the line that loads ‘config/deploy’:
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
Windows-safe reads. Any time Capistrano needs to read a file’s contents, it will now use the “b” flag, so that binary reads on Windows do not corrupt the file.
Cap shell and sudo. The Capistrano shell now properly recognizes sudo commands and prompts for the password correctly.
Use `match’ to check dependencies. There is a new remote dependency method for deploy:check: “match”. You can now look for arbitrary regular expressions in the output of various commands to see if things are set up correctly:
depend :remote, :match, "rake -V", /version 0\.7/
Namespaces#top. Sometimes you’ll find yourself wanting to execute a task from within another task, but the parent namespace of the target task is conflicting with a similarly-named namespace, and things are breaking. You can now use the “top” method to jump to the top of the namespace hierarchy:
namespace :apache do
namespace :deploy do
task :restart do
run "restart apache"
top.deploy.restart
end
end
end
Other changes. There are lots of other, smaller bug fixes and changes, too:
- Default to 0664 instead of 0660 on upload.
- Fix deploy:pending to query SCM for the subsequent revision so that it does not include the last deployed change.
- Prefer ‘Last Changed Rev’ over ‘Revision’ when querying latest revision via Subversion.
- Explicitly require ‘stringio’ in copy_test.
- When Subversion#query_revision fails, give a more sane error.
- Don’t run the upgrade:revisions task on non-release servers.
- Use the—password switch for subversion by default, but add :scm_prefer_prompt variable for those who’d rather not send the password on the command-line.
- Use sudo -p switch to set sudo password prompt to something predictable.
- Allow independent configurations to require the same recipe file within the same Ruby process.
- Allow auth-caching of subversion credentials to be enabled via :scm_auth_cache.
- Don’t let a task trigger itself when used as the source for an “on” hook.
- Add version_dir, current_dir, and shared_dir variables for naming the directories used in deployment.
- Use the :runner variable to determine who to sudo as for deploy:restart.
- Change the “-h” output so that it does not say that “-q” is the default.
Enjoy! And please report any bugs on the Rails trac, with the component set to “Capistrano”.
add to del.icio.us. look up in del.icio.us.
add to furlSun 14 October, 2007

add to del.icio.us. look up in del.icio.us.
add to furlSat 13 October, 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
This release closes a JSON XSS vulnerability, fixes a couple of minor regressions introduced in 1.2.4, and backports a handful of features and fixes from the 2.0 preview release.
All users of Rails 1.2.4 or earlier are advised to upgrade to 1.2.5, though it isn’t strictly necessary if you aren’t working with JSON. For more information the JSON vulnerability, see CVE-2007-3227.
Summary of changes:- acts_as_list: fixed an edge case where removing an item from the list then destroying the item leads to incorrect item positioning
- deprecated calling .create on has_many associations with an unsaved owner (like post = Post.new; post.comments.create)
- backport array and hash query parameters
- fix in place editor’s setter action with non-string fields
- updated config/boot.rb to correctly recognize RAILS_GEM_VERSION
To upgrade, `gem install rails`, set RAILS_GEM_VERSION to ‘1.2.5’ in config/environment.rb, and `rake rails:update:configs`.
add to del.icio.us. look up in del.icio.us.
add to furlFri 12 October, 2007

add to del.icio.us. look up in del.icio.us.
add to furl
在InfoQ China发了一篇介绍XRuby的文章。其实,对于之前听过我介绍XRuby的人来说,这篇文章的内容并不新鲜,因为基本上,这篇文章的内容脱胎于之前介绍XRuby的讲稿。虽然讲了几次,但还是应该把这篇文章写出来。一来,到场听介绍的人毕竟是少数,写出来看到的人应该可以更多,也让更多的人有机会了解XRuby,再有,内容写成文章需要比演讲时有更多的思考。所以,整体来说,内容叙述应该会更加准确。
这是一篇早就该写的文章,至少最初答应霍泰稳写这篇文章还是5月份的时候,7月份录我InfoQ访问的时候,又答应了Floyd完成这篇文章,可真正发布已经是十月份了。不过,这样一拖再拖也不是完全价值。在这段时间里,我在Agile Day讲了一次Ruby on JVM,让我对这个方面有了些新的思考,特别是把Ruby放在 JVM上的价值,这一点已经体现在这篇文章里了。另外,XRuby自身在这段时间中也发生了很大的变化,特别是Annotation的加入,让代码在表现形式上得到很大的进步。至少在我看来,最终体现在文章中的示例代码是可以接受的。
我希望,这篇文章可以成为一个起点。一方面,它可以作为让更多人了解XRuby的起点;另一方面,XRuby团队把它作为一个起点,向其它人展示XRuby中非常优秀的一面。当然,XRuby现在已经有了不少不错的文档。
已经有朋友给我建议,写一些更深入的东西,这也是我所希望的,只探讨一些比较浅的东西不过瘾。在XRuby开发过程中,有很多有趣的思考,我很愿意与人分享那种开发中的快乐。再有,写东西会促使人思考,随之而来的往往是发现不足,这也是有益于XRuby进一步改进的。
如果你希望了解或参与XRuby,不妨告诉我们,你想了解什么,也许,我们之后的文章会满足你!
add to del.icio.us. look up in del.icio.us.
add to furl
