Archive for January, 2008

/usr/bin/env: ruby -ws: No such file or directory

Thursday, January 31st, 2008

起因

我试图用 sow 工具来创建一个 gem ,但是当我执行 sow 的时候却得到了一个错误提示:

$ sow rmmseg
/usr/bin/env: ruby -ws: No such file or directory

经过

这是为什么呢?我首先找到了 sow 脚本的位置,发现它第一行的 Sha-Bang 如下:

#!/usr/bin/env ruby -ws

我立即尝试在 shell 下输入 /usr/bin/env ruby -ws ,发现一切正常,再创建了一个具有同样 Sha-Bang 的脚本,直接执行,却又同样的错误。这是为什么呢?

Read the rest of this page »

RMMSeg: Ruby 实现中文分词

Thursday, January 31st, 2008

我在前面曾经提到过,中文分词比较困难,不像英文那样,直接在空格和标点符号的地方断开就可以了。 Jack评论中提到即使是英文,在进行短语层次的分“词”时也会有类似的困难。还有在进行手写识别时,空格有时候不能很精确地识别出来,也会要用到中文分词中的一些技术。

RMMSeg 我近日做的一个 Ruby 的中文分词实现,下一步是和 Ferret 进行集成。不过,在介绍 RMMSeg 之前让我先来简要介绍一下中文分词。

如何分词?

那么中文分词究竟要如何做呢?想想你自己看到一个句子的时候,如何进行分词?似乎是及其复杂的吧?好像感觉到现在的电脑还达不到这个层次,至少一台普通 PC 机不可能拥有一个人的大脑那么多的后备知识可用。但是若是只要求百分之八九十的准确率的话,要实现一个分词算法也并不困难。

这里又要说 80/20 原则了,要实现一个在 80% 的情况下能工作的算法通常不会太难,但是要保证另外 20% 也能正常工作的话,通常难度相差不止 N 个数量级。何况这个问题并不是 100% 可解的,一些固有歧义的情况及时是人也无法选择一个更好的分词方法来。

Read the rest of this page »

让 secureCRT 和 OpenSSH 共享 Private Key

Wednesday, January 30th, 2008

TerminalsecureCRT 是 Windows 下一款非常优秀的 SSH 客户端软件(商业软件),目前它的最新版本是 6.0 ,从 5.5 版开始支持 OpenSSH 格式的 Private Key ,并可以把它自己的 Private Key 转换为 OpenSSH 格式。

OpenSSH 是 Linux 下广泛使用的 SSH 程序。我自己在前一段时间广泛使用的一对密钥是通过 secureCRT 生成的,最近需要在 Linux 下也使用密钥的方式进行 SSH 连接,维护多对 SSH 密钥是比较麻烦的事情,而且容易搞混,可是私钥格式并没有统一标准,各个程序之间的格式通常是不兼容的。

在网上搜索了一下,发现 secureCRT 从 5.5 开始支持 OpenSSH 格式的私钥了,当然,为了避免重新生成一对密钥,它还有把 secureCRT 格式的密钥转换为 OpenSSH 格式密钥的工具,这下就方便多了。

下面是转换步骤:

Read the rest of this page »

Ruby: 提升性能的几点尝试

Tuesday, January 29th, 2008

近日做一个 Ruby 的程序需要用到一个大约 2 MB 大小的词典,我把它构造在一个 Ruby 的 Hash 里,然而程序启动需要花上大约 4 秒多的时间,主要都是花在加载词典上了。虽然这个程序许多情况下可以在初始化之后处理许多数据,因此可以把启动时间忽略掉,但是在测试的时候还是让人相当不爽。于是就想看看是否可以改进。

首先我测试了只读入一个大约 2 M 的文件的操作,速度非常快,在我这里大约在 0.16 秒左右,然后尝试在读入每行的时候把数据加入到一个 Hash 中去,速度降低到了越 0.43 秒左右:

h = Hash.new
File.open("words.dic", "r") do |f|
  f.each_line { |l|
    h[l] = l
  }
end

虽然速度下降了,但是显然不是我前面的 4 秒多。问题在于:我的辞典并不是简单的每行一个单词。不过需要明确一点,如果要在 Hash 中构建一个辞典,上面是最基本的代码,因此上面这段代码的性能应该是性能极限。

Read the rest of this page »

Handling UTF-8 in Ruby

Monday, January 28th, 2008

Ruby 1.9.0 已经发布了,1.9 的一个重大改进就是对 Unicode 的支持,这里有一篇介绍 Ruby 1.9 中 Unicode 的文章,可惜是日文的,不过配合代码和部分汉字应该能理解大概意思。

在 Ruby 1.9 中,将如下代码保存为 UTF-8 编码,可以轻松运行通过:

# -*- coding: utf-8 -*-
 
require 'test/unit'
 
class TestUnicode < Test::Unit::TestCase
  def setup
    @str = '这是中文'
  end
 
  def test_size
    assert_equal 4, @str.size
  end
 
  def test_at
    assert_equal '这', @str[0]
  end
 
  def test_reverse
    assert_equal '文中是这', @str.reverse
  end
end

注意第一行的注释中的 coding: utf-8 是必须的(当然也可以通过其他各种方式来指定,不过我很喜欢这种方式,因为这样 Emacs 也可以认出这个文件的编码来)。在 Ruby 1.8 中就没有这么方便的事情了,不过由于 Ruby 1.9 刚刚发布,Ruby 1.9.0 又是“不稳定版本”,许多库还只能工作在 1.8 之下,所以还得有相当长一段时间内需要 Ruby 1.8 的相关 workaround 来处理 Unicode 以及国际化等相关的工作。

在 Ruby 1.8 中,可以使用全局变量 $KCODEjcode 来实现一些常用函数。例如,要使用 UTF-8 编码,首先把 $KCODE 设置为 'u' ,设置之前是这样:

Read the rest of this page »

中文真是复杂啊

Thursday, January 17th, 2008

平时用起来似乎感觉和英文没有什么大的区别,大概是人脑太强大了,中文和英文都是“小菜一碟”,所以不太能感觉得出区别吧,但是放到现在的电脑上就能明显感觉出区别来了。比如说输入,要依靠输入法,而且输入法的学问也很大。输入以后要显示,字体也是一个问题,英文字体文件可以很小,而中文的话通常会很大。最麻烦的应该还是做检索,要做索引的话需要进行分词,英文很方便,直接

text.split

Read the rest of this page »

no such file to load — mkmf

Wednesday, January 16th, 2008

在 Debian 这样有强大的包管理系统的发行版里面,通常会有许多地方和已有的插件管理系统有重叠,例如 Ruby 的扩展(gem)、Firefox 的扩展等等,用哪个管理系统就是仁者见仁了。全部都用系统提供的管理系统当然保证了统一性,更加方便。但是特定的管理系统通常更全更新。例如 Ruby 的话,安装扩展的时候我通常都是通过 gem 直接从 RubyForge 上安装的。

如果 Ruby 本身是通过 apt-get 安装的,然后通过 gem 来安装某个扩展时需要编译的话(例如 Hpricot 或者 Ferret 等),会出现如下错误:

/usr/bin/ruby1.8 extconf.rb install ferret
extconf.rb:11:in `require': no such file to load -- mkmf (LoadError)
        from extconf.rb:11

由于 mkmf.rb 并没有包含在 Debian 的 Ruby 包里面,需要安装相应的 dev 包,这里就是 ruby1.8-dev 了。装上之后就不会有这个问题了。

通宵排队买票

Tuesday, January 15th, 2008

我同 cc98 上一个去内蒙方向的土木的同学和 88 上的一个老乡一起在玉泉正门口通宵排队 15 个小时买火车票。也算是买到了吧,自贺一下。

昨天下午 5 点多到玉泉正门口,本来是想去城站排队的,好歹是室内,暖和啊,可是城站临时变更售票规则,不再提前 11 天出售卧铺票,真是奇怪,火车站反而不可以买,而代售点倒是可以买。总之,昨天下午我们三个人排在第 14、15、16 这三个位置,可惜我们三个人总共就要买 9 张票,没法轮班排队,因为每个人限买三张卧铺嘛。排在最前面的一波人好像是要买去重庆的票,听说是中午一点就过来的。他们似乎有很庞大的队伍,经常轮换。我们几个从紫金港过去,换了也没地方住。

Read the rest of this page »

一个时代的终结:MIT CS 6.001 课程停开

Wednesday, January 9th, 2008

今天在 newsmth 的 FuncProgram 版看到这个消息,真是大吃一惊。我在这篇文章中提过 MIT 的 CS 6.001 ,就是那个著名的教材和课程名称都叫做 Structure and Interpretation of Computer Programs 的程序设计基础课程。版上贴出来的链接是这个

CS 6.001 是 Hal Abelson 和 Gerry Sussman 于 1980 年创立,以 Scheme 语言为基础讲述程序设计的原理(听说后来换成 Python 了?)。事实上,Scheme 的语法简介明了,很适合于把注意力集中在讲述“如何编程”上面,而不是像我们现在许多大学开的程序设计课程那样,整个学期都是在讲语法。

然而课程整改以后这门课将从 MIT 消失,不论什么原因吧,始终是会觉得惋惜的。Sussman 几年前说过他要来上这门课程的最后一节课。事实上,这门课是在上课时间很早(早上 10 点,在 MIT 那里算是很早了,看来 MIT 的学生比我们这里睡懒觉还严重啊 -.-bb),然而最后一节课大家都来了,包括以前上过这个课的学生,甚至还有从未修过这门课程的学生,都来为这门课程道别。还有人把教室的号码(原本是 32-123 )换成了 6.001 :

Read the rest of this page »

Automate interaction with websites using Mechanize

Wednesday, January 9th, 2008

rubyMechanize 是一个用于在 Ruby 脚本里将与 Web 页面的交互工作自动化的库。它会自动处理 Cookie 、重定向、Referer 之类的东西,使用起来非常方便。我就用我今天写的一个小脚本作为例子来介绍一下 Mechanize 吧!

其实我是在寻找 Ruby 里面处理 Cookie 的库的时候找到它的。学校的网络以前是要先通过一个 Web 页面登录才能上网的(可恶的电信!),早就有前辈们写了上网登录脚本,方便使用(事实上在 Linux 下想要使用学校提供的 201+ 卡方式访问校外网的话,只有用登陆脚本了,电信提供的 IE 插件根本没法用)。可是脚本是用 perl 写的,我倒是不想为了上网自动登录大费周章地去装一个 Perl (在 Windows 下),不过倒是装了 Ruby ,便想自己写一个吧。

看了那个 Perl 脚本,又抓了写包看了看,好像挺麻烦的,有重定向、还要处理 Cookie ,Ruby 标准库 Net::HTTP 似乎没有提供 Cookie 的解决方案,也不想手工处理,便去网上搜索,一下子就找到了 Mechanize 这个库,这难道不正是我要找的那个东西吗?!

粗略地扫描了下他的 README ,便开始在 IRB 里做实验,先 new 一个 agent 出来:

require 'rubygems'
require 'mechanize'
 
agent = WWW::Mechanize.new

Read the rest of this page »