准备实现文章底栏
放 “相关文章” 或者订阅信息比较合适~
为了尽可能不多占用文章的版面,准备用 Tab 页来显示各个项目:

像 Lua 那样引用 Hash 元素
Lua 中的 Table 可以拿来当作多种数据格式来使用,比如 Hash ( Dictionary ):
-
h = {a=1,b=2,c=3}
-
print(h['a'])
-
1
最爽的是,可以用 h.a 这种形式来引用 Hash 中的元素:
-
print(h.a)
-
1
利用 Ruby 的 method_missing,也可以这样爽一把,仅仅需要:
-
class Hash
-
def method_missing(method, *args)
-
self[method]
-
end
-
end
即可,测试:
-
h = {:a => 1, :b => 2, :c => 3}
-
puts h.a
-
1
只要 hash 的 key 不要与 Hash 内置的方法重名就可以了~ ![]()
啥?还要实现赋值? 这个好办,只要将上面的代码改为:
-
class Hash
-
def method_missing(method, *args)
-
if method.to_s =~ /=$/
-
self[method.to_s.chop.to_sym] = *args
-
else
-
self[method]
-
end
-
end
-
end
就可以了,测试:
-
h = {:a => 1, :b => 2}
-
h.a = 456
-
puts h.a
-
456
感觉不错~ ![]()
哇卡卡,大菠萝归来~
嗯嗯,基本不怎么玩 PC 游戏,Diablo 算是个例外,高中时期陪伴我度过无数无聊的时光,大学期间还拿出来复习了 2 次
。
Diablo III 大期待~ 按暴雪的风格,估计得折腾两三年,反正现在发布了我也没空玩,还是晚点的好,咔咔~ ![]()

郁闷的校园网
这两天不知道怎么了,校园网开始不断的抽筋,正常上网一段时间 ( 1~3 个小时不等) 之后,突然一下就断网一段时间 ( 半小时~2 小时不等 )…… ![]()
网络是好的,抽筋的只是那个“认证系统” -- 传说中的 Dr.COM……
每次上网上到一半,点个链接,立马出现了个在 Firefox 中显示的七扭八歪的 "XX 大学网络系统" 网页,就知道又开始抽了……![]()
客户端上看貌似是认证服务器翘辫子了,这已经很郁闷了,更加郁闷的是这个客户端……
每次断网,这个客户端还是登入的状态,想重新登录只有先注销,不过服务器翘了,点击注销之后,就要等半分钟超时出错才算完,但是不注销不能退出这个程序,所以只好直接杀死进程……
最郁闷的是,没有自动重连,点击登录之后,尝试 3 次就歇菜了,我又不知道服务器什么时候能恢复,只好一遍又一遍的去点登录……
每次断网,都有种想
的冲动……
目前,已经把这个客户端当作 防 RSI 的软件,只要它一抽,我就起来活动一下,喝喝水,收拾收拾屋子,等我折腾完了,服务器也差不多抽好了……
Firefox 3 Release
Firefox 3 终于发布了,虽然目前官方网站的下载按钮上面还是写着 2.0.0.14,不过标题和新的背景已经换上了~ 

Gentoo 竟然第一时间在 portage 里更新了,mozilla-firefox-bin-3.0 已经可以 emerge ~ 
不过:
fb66b2c2639dc3216abb0c6e1b3dc668 firefox-3.0rc3.tar.bz2
fb66b2c2639dc3216abb0c6e1b3dc668 firefox-3.0.tar.bz2
也就是说,正式版就是 rc3,对于和我一样一直在用 rc 系列的同学来说可能有点失望吧~ ![]()
现在就等着还没有兼容 Firefox 3 的插件快快更新了~
尽情享受 Firefox 3 吧~ 
用 Ruby 求定积分
纯属无聊……![]()
曾经以为求积分之类的是个很复杂的过程,对那些可以求出积分值的计算程序佩服不以,昨日脑子不知道为什么忽然想到这个问题,翻了翻书,发现这个问题很简单~ ![]()
用最简单的矩形法,Ruby 代码如下:
-
def integral(a, b, n = 100)
-
sum = 0.0
-
dx = (b - a)/n.to_f
-
n.times do
-
a += dx
-
sum = sum + (yield a)*dx
-
end
-
sum
-
end
n 为精度,Ruby 的 block 真方便,如果要求:

那么就是:
-
integral(0, 1) {|x| x**2 - x**3}
如果要求:

那么就是:
-
integral(0, Math::PI) {|x| Math.sin(x)}
如果函数很复杂,也可以在外面定义一个 f(x),然后写成 integral(a, b) {|x| f(x)},相当美观~ ![]()
看看结果:
-
puts integral(0, Math::PI) {|x| Math.sin(x)}
-
>> 1.99983550388745
的准确值是 2,看来精度还不错~ ![]()
嗯嗯……其实本文的真正意义在于,很久很久之前给 is-Programmer 实现了插入 TeX 公式的功能,这是我第一次用上…… ![]()
用 File.expand_path 过滤文件名
一些情况下,要从用户哪里得到文件名或者目录名参数,比如文件读取、上传、删除,创建目录,还有 typo 那个 theme_controller 中的 css 和 js 缓存。
恶意用户可以输入含有 "../.." 这样的字符的参数,从而跳转到上级目录,读取或者删除一些其他目录的文件,所以必须要过滤,比如 typo 的 theme_controller.rb 代码中:
-
def render_theme_item(type, file, mime = nil)
-
...
-
if file.split(%r{[\\/]}).include?("..")
-
return (render :text => "Not Found", :status => 404)
-
end
-
...
file 来自 params[:filename],检查 file 中是否含有 "..",如果有的话,就不做任何动作返回 404。
但是这样并不能解决所有的问题,参数可以被 URI 编码成 %xx%xx 的形式,而且天知道还有什么字符可以跳转到上级目录
。
最近在看 《Adcanced Rails》这书,上面写了种不错的方法:
-
name = params[:filename]
-
-
base_path = File.expand_path(File.join(RAILS_ROOT, "public"))
-
file_path = File.join(base_path, name)
-
-
if File.expand_path(file_path).start_with?(base_path)
-
data = File.read(file_path)
-
else
-
raise "Access denied"
-
end
File.expand_path 这方法可以扩展路径字符中所有的特殊字符,包括 "~", "..", ".",形成平坦的路径字符串( 原来我一直以为 File.join 也有这个功效……
),最后只要检查一下文件的最终地址,开头是否为安全的目录即可,这样就可以轻松的将用户的读取范围限制在 base_path 之下了~ ![]()
编译原理,再开~
看完了《形式语言与自动机导论》,虽然后面的章节明显没有前面看得认真
,但是对形式语言这块算是有了个总体的认识,DFA、正则表达式、Context-Free Languages、图灵机这些东西之间有什么关系,顿时清楚了很多~ ![]()
当初看得屁滚尿流败下阵来的《编译原理》,也准备再开,虽然还是没有信心能看完,但是应该比上次好得多
。
伟大的编译器之神,保佑我吧~~ ![]()
Chito 1.0.6 上传完毕
最近比较折腾,拖了很久,幸运的是修正了在 is-Programmer 使用期间发现的 bug
,更新内容可以参考这里。
自写 html 闭合的一个 Bug
前阵子拿自己写的那个 html 闭合函数,洋洋得意的替换掉了 RubyfulSoup 那个大库,结果却没有发现隐藏在其中的一个 Bug。
当初虽然找了不少 html 样本进行测试,最后却忘记测试 self-close 标签存在的情况,多亏了 獨立的圓 帮我找出了这个问题
。
Bug 就是如果 html 中有 <br/> <img ... /> 这样的标签,闭合函数就会错误的再追加 </br> </img> 这样的标签在简介末尾,要不是导致 獨立的圓 的 Blog 格式混乱,不知道什么时候才能发现这个问题。
知道了问题所在,修正就很简单了,下面就是改善过的版本,不知道还有没有没有考虑到的地方,高亮部分是改动的部分:
-
def close_html(html)
-
stream = html.scan( /<\s*[\/]*[^>^\/]+>/ ).map { |x| x[ /<\s*([^>^\s]* )[^>]*>/, 1]}
-
stack = []
-
stream.each do |x|
-
if x =~ /^\//
-
stack.pop if x[1..-1] == stack.last
-
else
-
stack.push x
-
end
-
end
-
stack.reverse.each {|x| html << "</#{x}>\n"}
-
html
-
end