Category: Ruby

43 posts

MSTC Staff 的睡眠趋势

大约是从去年寒假的时候开始,我就经常在 cc98 的 MSTC 版上发“晚安帖”,就是每天晚上睡觉的时候发一个帖子说一声晚安,后来版面上时常出现一大堆晚安帖的情况,遭到大家的抗议。 :p 后来只好集中到了一个帖子里面,养成了习惯大家也都时常来说晚安。 不管是早有预谋还是心血来潮,我对这个晚安贴的内容分析了一下,得到了类似于下面的结果: 其中横坐标是日期,纵坐标是睡觉时间,由于大家都睡得比较晚,所以把第二天凌晨的时间也记作当天晚上(如 25:00 就是第二天凌晨 1:00 [...]

On the Rubinius FFI

.rbx-doc-hdr { text-align: right; font-family: monospace; color: black; margin: 7px 20px -13px 5px; padding-right: 8px; border-right: #BAC8D4 7px solid; background-color: #ECF4FB; border-bottom: 1px dotted #C0C0C0; } Contents: The need for glue code The Rubinius FFI The FFI document Rubinius FFI [...]

用 Graphviz 来做图的 Visualization

“编译系统设计”课有一个作业是做一个某语言的 parser ,生成一棵语法树,并用合适的方法把这棵语法树显示出来。我用 Graphviz 来做了 visualization 的部分。这是一个用来做图的 visualization 的很方便的工具,语法树作为一棵树,其实是一个有向无环图了,所以用这个来做其实也是很方便的。 其实作业主要分为两个部分:分析和 visualization 。“某语言”可以是自己定义的,我一开始想做 Scheme 的语法分析,不过后来想想还是算了,那个实在是太简单了,恐怕到时候助教不让过。题目要求用 YACC 或者递归下降的方式进行分析。YACC [...]

[ANN] rmmseg-cpp 0.2.5 released

I developed rmmseg-cpp about half a month ago. After running in JavaEye, it is said the performance is good and the memory usage is stable. I'm very glad to see rmmseg-cpp be used in production.

Rubyforge support git now

不知道是不是我火星了,今天去 Rubyforge 注册 rmmseg-cpp 项目的时候发现在 SCM 那里可以选 git 了。不知道是什么时候加上的支持,这下应该会方便许多了。不过刚注册的项目还没有通过审核,到时候立即试用一下,这样在 github 和 Rubyforge 同时有一个 repo 应该也是能很方便地同步的了! :)

Play with GC: mark your treasure

Garbage collecting is amazingly useful. It is a must-have of any modern language. You never need to concern about when to free the allocated memory again. Just allocate, those objects not used will be collected automatically at a some time. Yes, it's true. But, wait, it's not true! I still remember [...]

rmmseg-cpp: rmmseg in C++

RMMSeg is an implementation of MMSEG Chinese word segmentation algorithm. It features full integration with Ferret. The original version is written in pure-Ruby, which includes two algorithms: Complex Algorithm: Maximum matching with three-word chunk filtering. The accuracy is good. But the [...]

Inside the {C++, Java, Lisp, Python, Ruby} Object Model

We just held a technical salon today named "template<language L> Inside the L Object Model". When I was looking at some code of Ruby, I found the object model is very different to a static language like C++. So I suggested the idea of discussing various object model of different [...]

YARV (The Official VM for Ruby 1.9) Instruction Set

YARV is Yet Another Ruby VM. But it is the official Ruby VM since Ruby 1.9. It is a stack-based VM which runs the YARV bytecode, or intcode because each element of the instruction sequence is in fact stored as an int. There is an instruction table for YARV on the original YARV homepage, but it is [...]

BleakHouse 4! Find memory leak in your Ruby program!

今天看到 BleakHouse 发布了第 4 版的消息:采用了全新的实现: ...there is no framing necessary, and the analysis task runs in seconds instead of hours. 我在“内存泄漏分析工具的尴尬”这篇文章中曾经介绍过 BleakHouse ,不过那个时候用 BleakHouse 会产生出无比巨大的 dump 文件,并且分析过程需要花费非常多的内存和时间,有时基本成了不可能完成的任务。现在看到 v4 发布消息里提到了新的实现,实在是大喜!因为这本身是一个非常不错的工具。如果你有发现你的 Ruby [...]

Ruby on Crack: yet another web framework

:D 愚人节里各个社区里的气氛都活跃了许多,在 Ruby-talk 的邮件列表里发现了 N 个 Ruby fork 要发布了,还有用 PHP 写的 Ruby 。其他社区也很活跃,Java 似乎是今年的一个主角:各种各样的项目都要迁移到 Java 了。 :D 不过令我敬佩的是虽然只是愚人节的玩笑,许多人都很细心地去做,比如前面的这个叫做 Brobinius 的 Ruby fork 还专门做了一个网站。还有 Antonio Cangiano 的 Ruby on Crack ,他最后一段描述的不同的人对 Ruby on Crack 的反馈: “Those who use Crack can [...]

[ANN] RMMSeg 0.1.4 Released

我今天发布了 RMMSeg 0.1.4 版。性能有少许提升,现在使用 ComplexAlgorithm 大约有 20KB/s 的速度,而 SimpleAlgorithm 差不多是 60KB/s 。我在一个 branch 里用 C 来实现了一部分代码,减少了许多 String 的构造,可是效果并不明显,让我非常失望,而且由于我在前一篇 Blog 里提到的 Ruby 关于 Hash 的 Bug ,需要打过 patch 的 Ruby 才能正常运行,所以并没有把带 C 扩展的版本包含在这个 Release 中。 下面是 RubyForge 上的 Release announcement:

Fixnum Overflow in Ruby’s Hash Implementation

Ruby's build-in Hash is the first-choice if you want to do searching. Using your own customized object as hash key is simple: define the following two method for your object: hash: to get the hash code of the object. eql?: to compare whether two object are equal. When working to improve the [...]

A Better method_missing

method_missing 是 Ruby 用于实现其动态性的一个重要成员。简而言之就是在调用一个对象的某个方法的时候发现这个方法不存在,于是会触发 method_missing ,进而做一些事情,比如转发这个方法,甚至根据需要定义那个方法让下次调用的时候不会产生 method_missing ,另外这也是制作 DSL 的一个重要工具。 下面是一个简单的 DSL 的例子:

内存泄漏分析工具的尴尬

Ruby 内置了 ObjectSpace 可以用来分析当前生存的对象,但是这样的方法有时候并不好用,而且使用 ObjectSpace 会影响到它自己。Evan Weaver 做的 BleakHouse 工具则用 C 直接分析 Heap (以前的版本也是使用 ObjectSpace),可以得到更精确的结果,可以用于内存泄漏的检测。 不过它的文档比较简略, Rails 好像可以直接用,而非 Rails 程序则只要“构建一个 BleakHouse::Logger 对象,并在合适的时候调用其 snapshot 方法”。我不是很清楚什么是“合适的时候”,我尝试在每一轮调用主要执行代码的时候调用一次 [...]

[ANN] RMMSeg 0.1.2 Released

RMMSeg 发布了 0.1.2 版,主要是对性能进行了一些改进,以下是引用 RubyForge 上的通告:

Ruby Hacking Guide 中文版

Ruby Hacking Guide (简称 RHG)是青木峰郎创作的一本剖析ruby实现的书。对于 Rubyer 来说是非常不错的资料,可惜是用日文写成的。在 RubyForge 上有一个项目致力于将它翻译为英文,在 Google Code 上也有 dreamhead 他们发起的一个中文翻译项目。 目前中文版的翻译进度比英文版要快,但是仍然需要大家的参与和支持,这里引用他们的一段话: 如你所见,RHG 中文版目前还没有全部完成。所以,欢迎有兴趣的朋友加入到 RHG 中文版的制作过程中来。 如果你懂日语,你可以加入翻译团队,协助完成剩余部分的翻译,或是校验已完成部分的正确性。 [...]

Memory leak profiling with Ruby: ObjectSpace

内存泄漏?!不是有 Garbage Collector 吗?为什么在带 GC 的语言里还会有内存泄漏?GC 难道不是来帮助我们摆脱万恶的内存分配问题的吗?确实如此,但是 GC 也不是万能的。垃圾收集器并不知道你需要用到哪些对象,所以它假定能被你(通过某个变量直接或间接)引用到的对象是你会用到的,而其他的则是垃圾——这是相当保守的做法,但是至少是正确的。但是这样带来的一个问题就是:如果你(有意或者无意地)持有了一些(你以后根本不会用到的)对象的引用(例如,通过一个全局变量),就造成了内存泄漏。 看起来在带 GC 的语言里的内存泄漏比普通的 C 语言类的程序里的内存泄漏问题更难处理。在 Ruby [...]

We read Knuth so you don’t have to

来自 Python Cookbook (第 5 章:Searching and Sorting)的 Quote : We read Knuth so you don't have to. 所以在 Python 中,如果要排序,尽量使用内置的 sort 方法;如果要做搜索,尽量使用内置的 dictionary 工具,因为它们集中了 Knuth 先生的经典砖头里面的近 800 页的关于排序和搜索的详细讨论。当然,在 Ruby 中肯定也是差不多的。 ;)

Coroutines and Semi-Coroutines

Ruby 1.9 中引入了 Fiber 用于支持 Coroutine 。事实上 Fiber 并不是一个 Coroutine ,而是 Semi-Coroutine ,或者叫做 Asymmetric Coroutine 。因为它只能将执行权返回给调用者,而完整的 Coroutine 可以自由转移运行权。 Ruby 1.9 也提供了 Fiber::Core 用于支持“正宗”的 Coroutine 。关于 Semi-Coroutine 和 Coroutine 的等价性似乎有些争论。下面是一个 Fiber 的例子: fib = Fiber.new do x, y = 0, 1 loop do [...]

Screencast: RMMSeg/Ferret Demo

这个 Demo 通过经典的用 Rails 建立 blog 的例子演示了如何使用 act_as_ferret 快速构建一个全文索引,并演示了 RMMSeg 中文分词的效果。 Ferret 是一个 Ruby 的高性能的全文搜索引擎库,可以说是 Ruby 的 Lucene 。 RMMSeg 是 MMSEG 中文分词算法的 Ruby 实现。RMMSeg 的实现包括了整合 Ferret 的 RMMSeg::Ferret::Analyzer ,可以为 Ferret 提供中文分词的功能,实现中文的全文索引。 acts_as_ferret 是一个 Ruby on Rails 的插件,可以让 Rails [...]

Rubinius 的首页改版了

好久没有去看过,居然改头换面了,从前 Rubinius 的首页里面的信息量并不比 lifegoo team 的首页多多少。 :p 不过现在换了个风格,而且 Documentation 一页似乎多了不少东西! :D Rubinius 是一个类似于 SmallTalk-80 架构的 Ruby 虚拟机,大部分代码用 Ruby 本身来写成:例如 byte-code 的编译器,这样字节码甚至可以直接在其他 Ruby 实现(比如 JRuby 或者 MRI)上加载。虽然说现在 Rubinius 还不太成熟,在各种测试中似乎都是在各个 Ruby [...]

[ANN]RMMSeg 0.0.1 Released

RMMSeg 是 MMSEG 中文分词算法的 Ruby 实现。可以作为独立的程序运行,也可以方便地和 Ferret 进行集成。 今天凌晨在完成了与 Ferret 的集成工作以后,我发布了 0.0.1 版,可以从 RubyForge 进行下载,也可以直接使用 RubyGems 进行安装: $ sudo gem install rmmseg 下面是引用 RubyForge 上的 Announcement :

Ruby: Caution with sub/gsub

如果你不喜欢听我讲故事,那么请直接跳到末尾。其实故事很简单,最近几天的故事都是和 RMMSeg 有关。这次我是在做 RMMSeg 的主页,昨天晚上(或者说今天凌晨)我做完了和 Ferret 的集成,并发布了 0.0.1 版。可以看到,主页我也做好了。 其实主页早就做得差不多了,只是还缺一个和 Ferret 配合使用的例子。现在那里已经有一个例子了,用 Ferret 的 Highlight 输出为 HTML 格式: highlights = $index.highlight("content:#{key}", id, :field => :content, :pre_tag => "", [...]

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

起因 我试图用 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 的脚本,直接执行,却又同样的错误。这是为什么呢?

RMMSeg: Ruby 实现中文分词

我在前面曾经提到过,中文分词比较困难,不像英文那样,直接在空格和标点符号的地方断开就可以了。 Jack 在评论中提到即使是英文,在进行短语层次的分“词”时也会有类似的困难。还有在进行手写识别时,空格有时候不能很精确地识别出来,也会要用到中文分词中的一些技术。 RMMSeg 我近日做的一个 Ruby 的中文分词实现,下一步是和 Ferret 进行集成。不过,在介绍 RMMSeg 之前让我先来简要介绍一下中文分词。 如何分词? 那么中文分词究竟要如何做呢?想想你自己看到一个句子的时候,如何进行分词?似乎是及其复杂的吧?好像感觉到现在的电脑还达不到这个层次,至少一台普通 PC [...]

Ruby: 提升性能的几点尝试

近日做一个 Ruby 的程序需要用到一个大约 2 MB 大小的词典,我把它构造在一个 Ruby 的 Hash 里,然而程序启动需要花上大约 4 秒多的时间,主要都是花在加载词典上了。虽然这个程序许多情况下可以在初始化之后处理许多数据,因此可以把启动时间忽略掉,但是在测试的时候还是让人相当不爽。于是就想看看是否可以改进。 首先我测试了只读入一个大约 2 M 的文件的操作,速度非常快,在我这里大约在 0.16 秒左右,然后尝试在读入每行的时候把数据加入到一个 Hash 中去,速度降低到了越 0.43 秒左右: h = Hash.new File.open("words.dic", "r") do [...]

Handling UTF-8 in Ruby

Ruby 1.9.0 已经发布了,1.9 的一个重大改进就是对 Unicode 的支持,这里有一篇介绍 Ruby 1.9 中 Unicode 的文章,可惜是日文的,不过配合代码和部分汉字应该能理解大概意思。 在 Ruby 1.9 中,将如下代码保存为 UTF-8 编码,可以轻松运行通过: # -*- coding: utf-8 -*- require 'test/unit' class TestUnicode 注意第一行的注释中的 coding: utf-8 是必须的(当然也可以通过其他各种方式来指定,不过我很喜欢这种方式,因为这样 Emacs 也可以认出这个文件的编码来)。在 Ruby [...]

no such file to load — mkmf

在 Debian 这样有强大的包管理系统的发行版里面,通常会有许多地方和已有的插件管理系统有重叠,例如 Ruby 的扩展(gem)、Firefox 的扩展等等,用哪个管理系统就是仁者见仁了。全部都用系统提供的管理系统当然保证了统一性,更加方便。但是特定的管理系统通常更全更新。例如 Ruby 的话,安装扩展的时候我通常都是通过 gem 直接从 RubyForge 上安装的。 如果 Ruby 本身是通过 apt-get 安装的,然后通过 gem 来安装某个扩展时需要编译的话(例如 Hpricot 或者 Ferret 等),会出现如下错误: /usr/bin/ruby1.8 extconf.rb [...]

Automate interaction with websites using Mechanize

Mechanize 是一个用于在 Ruby 脚本里将与 Web 页面的交互工作自动化的库。它会自动处理 Cookie 、重定向、Referer 之类的东西,使用起来非常方便。我就用我今天写的一个小脚本作为例子来介绍一下 Mechanize 吧! 其实我是在寻找 Ruby 里面处理 Cookie 的库的时候找到它的。学校的网络以前是要先通过一个 Web 页面登录才能上网的(可恶的电信!),早就有前辈们写了上网登录脚本,方便使用(事实上在 Linux 下想要使用学校提供的 201+ 卡方式访问校外网的话,只有用登陆脚本了,电信提供的 IE 插件根本没法用)。可是脚本是用 perl [...]

Running RSpec in Emacs

RSpec is a Behaviour Driven Development framework for Ruby. It's output format can be customized. However, the default format works well in Emacs's compilation-mode. Type M-x compile and input spec file_name_spec.rb. The result will be prompted at a new buffer. Some useful information are [...]

RubyConf 2007 video 释出!

RubyConf 2007 演讲的全部视频最近由 Confreaks 公司公布(Creative Commons Attribution-ShareAlike license)出来,可以在这里在线观看或者下载 AVI 格式(H.264)的视频。 这么多牛人的怎么多精彩的演讲,真是令人激动啊!我把他们下载下来了,这样离线的时候也可以看。我还把他们传到了 88 CompLang 版的 FTP 上,校内的朋友们可以直接去那里下载。 :) 我虽然还没有来得及看所有的演讲,但是随便看了几个都是非常有趣的(当然,也是非常精彩的),我这里随便介绍一两个,相信你一定也会喜欢的! Hurting Code [...]

Ruby 1.9.0 is released

Ruby 1.9 在圣诞节如期发布啦! Hi, We are happy to announce of the release of the 1.9.0 the development release. You can fetch it from: ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.bz2 407cc7d0032e19eb12216c0ebc7f17b3 ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz [...]

Continuation + Y Combinator

我在介绍 Continuation 的文章中提到了一个 create_iterator 的实现,它接受一个函数名,内部去调用这个函数而实现 iterator 。最初我是想让它接受一个 block 的,但是后来却改成了函数名,正是在做二叉树的遍历时出了问题:二叉树遍历是一个经典的递归程序,而 block 没有名字,无法做递归,只好作罢。 不过在前一篇文章中我又介绍了 Y Combinator (其实我也是在一边学习的)正好可以用来做匿名递归,刚好可以把这两者结合在一起啦! 原来的 create_iterator 是这样的:

the Y Combinator

今天看到 A Use of the Y Combinator in Ruby 这篇文章,却被他的代码搞晕了,半天看不明白,于是只好另辟蹊径,不看他的代码,却自己来写一下,如果我写出来的代码和他一样,那自然就明白了,如果不一样,也好对比一番,相信也更容易理解了。 这里要解决的问题大致就是“匿名递归函数”的问题。递归函数大家都知道了,例如经典的阶乘函数: def fact(n) if n == 0 1 else n*fact(n-1) end end 匿名函数也没啥,在许多语言里,函数就和普通的值没有什么区别,不一定非要有一个名字,例如 lambda 就可以创建一个匿名函数: func = [...]

Write a Scheme Interpreter in Ruby(2): THE Interpreter

在上一篇文章中我们实现了对 scheme 代码的 parse 和 analyze 过程,并得到了一些可以直接 eval 的对象(String ,Symbol ,Number 和 Cons ),可是光凭这些并不足以让我们的解释器跑起来。这次我们要添加必要的代码,实现一个真正可运行的解释器。 在前面的代码中,我们已经实现了 scheme 中的几个基本对象的求值:作为 atom 的 String 、Symbol 和 Number 以及作为 list 的 Cons 都已具体实现了 eval 方法。事实上 atom 的求值已经不需要加什么其他代码了,但是 Cons 类却是耍了一个把戏,仔细看 Cons [...]

Write a Scheme Interpreter in Ruby(1): Parser & Analyser

也算是突然心血来潮吧,就想写一个 Scheme 的解释器,其实也是心血来潮了许多次了,只是一直都只是一个想法,最主要的原因还是因为自己对编译原理一无所知吧,也许明年上过编译原理课之后就好写了。不过这次真是心血来潮了,拦都拦不住,怕是等不到明年了。 不管写得出来写不出来,也都先试试吧!多次见石老师演示过 boost::spirit ,计算理论课上也学过了上下文无关文法,似乎还是知道个大概。于是我就开始找 Ruby 的 parser 库。 好像 parser 也有许多种,什么 Recursive Descent [...]

Multiton

Multiton 类似于 Singleton ,目的是要保证某种单一性。但是和 Singleton 的一个区别就是:Singleton 对于一个类只可能有一个对象,而 Multiton 则可能有多个对象,仅当用于构造的参数相同时,才保证唯一性。有许多地方都有这种模式的应用,例如 Lisp 或者 Ruby 里的 symbol ,同名的 symbol interned symbol 总是同一个对象。还有 Java 里的 String 也是这样的。 最近心血来潮在用 Ruby 做一个玩具级别的 Scheme 解释器,要表示 Scheme 里的 symbol 、number 和 string [...]

More on Continuation

我在前一篇文章中用构造二叉树的 iterator 的例子来介绍了一下 Continuation 。Jack 在评论中向我提了两个问题: many people know about the CPS transformation, and callcc as a means to get hold of the implicit continuation (”the rest of the computation”), but we often have a hard time using continuations: there’s a large gap between [...]

Continuation

Continuation 是什么?简而言之,就是代码执行状态,利用它可以把当前的执行状态保存起来,以供以后调用。Scheme 应当是最早支持完整的 Continuation 的语言了,事实上从理论上来说,任何支持 Closure 的语言都能手工实现 Continuation ,不过许多语言还是提供了现成的 Continuation 的支持,例如 Ruby 就有一个类似于 Scheme 的 call/cc(call-with-current-continuation) 的函数 callcc (因为“/”在 Ruby 里面不能作为变量名,所以最多只能做到这么像了 ;) )用于支持 [...]

nXhtml: tame your rhtml files

I personally use Emacs as an IDE to develop rails project. Equipped with emacs-rails, it becomes a powerful IDE for rails developing. However, you may noticed, it doesn't have full support for rhtml files. You can use html-mode to edit rhtml files, it is already good enough. But is is of course not [...]

memoize in Ruby

Common Lisp 的经典书《On Lisp》的 5.3 节叫做 Memoizing 。书中讲到了将函数调用的返回值缓存起来的一种技术。这本来是一种非常常见的技术,但是《On Lisp》让我看到了动态语言的精练之处,这样的一种技术被抽象成一个通用的函数,将任意一个函数传入 memoize ,就会得到一个经过包装的函数,并且它已经具备了缓存的能力: (defun memoize (fn) (let ((cache (make-hash-table :test #'equal))) #'(lambda (&rest args) (multiple-value-bind (val win) [...]

Ruby 里的元编程

关于元编程 Wikipedia 上关于元编程的定义说元编程就是将程序作为数据进行处理。“用程序来处理程序”,这就是“元”的来源了,这本身是一个容易产生混淆的地方,就像“用语言来描述语言”一样,数学上的许多悖论就来自于此呢。幸好我们用的编程语言比自然语言要简单许多,并且都有严格的定义规范,有兴趣的人可以尝试在自己喜欢的编程语言里面构造一下 “This statement is false” 这个经典悖论。 回到元编程,程序处理程序可以分为“处理其他程序”和“处理自己”,对于前者,有我们熟悉的 lex 和 lacc [...]