Jul 10, 2008
翻译一篇技术评论社的文章,是讲memcached的连载。fcicq同学说这个东西很有用,希望大家喜欢。
我是mixi株式会社开发部系统运营组的长野。
日常负责程序的运营。从今天开始,将分几次针对最近在Web应用的可扩展性领域
的热门话题memcached,与我公司开发部研究开发组的前坂一起,
说明其内部结构和使用。
(Read More)
Jul 8, 2008
毋庸多言,在vim中正则表达式得到了十分广泛的应用。
最常用的 / 和 :s 命令中,正则表达式都是不可或缺的。
下面对vim中的正则表达式的一些难点进行说明。
关于magic
vim中有个magic的设定。设定方法为:
:set magic " 设置magic
:set nomagic " 取消magic
:h magic " 查看帮助
vim毕竟是个编辑器,正则表达式中包含的大量元字符如果原封不动地引用(像perl那样),
势必会给不懂正则表达式的人造成麻烦,比如 /foo(1) 命令,
大多数人都用它来查找foo(1)这个字符串,
但如果按照正则表达式来解释,被查找的对象就成了 foo1 了。
于是,vim就规定,正则表达式的元字符必须用反斜杠进行转义才行,
如上面的例子,如果确实要用正则表达式,就应当写成 /foo(1) 。
但是,像 . * 这种极其常用的元字符,都加上反斜杠就太麻烦了。
而且,众口难调,有些人喜欢用正则表达式,有些人不喜欢用……
为了解决这个问题,vim设置了 magic 这个东西。简单地说,
magic就是设置哪些元字符要加反斜杠哪些不用加的。
简单来说:
- magic(\m):除了 $ . * ^ 之外其他元字符都要加反斜杠。
- nomagic(\M):除了 $ ^ 之外其他元字符都要加反斜杠。
这个设置也可以在正则表达式中通过 \m \M 开关临时切换。
\m 后面的正则表达式会按照 magic 处理,\M 后面的正则表达式按照 nomagic 处理,
而忽略实际的magic设置。
例如:
/\m.* # 查找任意字符串
/\M.* # 查找字符串 .* (点号后面跟个星号)
另外还有更强大的 \v 和 \V。
* \v(即 very magic 之意):任何元字符都不用加反斜杠
* \V(即 very nomagic 之意):任何元字符都必须加反斜杠
例如:
/\v(a.c){3}$ # 查找行尾的abcaccadc
/\m(a.c){3}$ # 查找行尾的(abc){3}
/\M(a.c){3}$ # 查找行尾的(a.c){3}
/\V(a.c){3}$ # 查找任意位置的(a.c){3}$
默认设置是 magic,vim也推荐大家都使用magic的设置,在有特殊需要时,直接通过 \v\m\M\V 即可。
本文下面使用的元字符都是 magic 模式下的。
量词
vim的量词与perl相比一点也不逊色。
vim | Perl | 意义 |
* | * | 0个或多个(匹配优先) |
\+ | + | 1个或多个(匹配优先) |
\? 或 \= | ? | 0个或1个(匹配优先),\?不能在 ? 命令(逆向查找)中使用 |
\{n,m} | {n,m} | n个到m个(匹配优先) |
\{n,} | {n,} | 最少n个(匹配优先) |
\{,m} | {,m} | 最多m个(匹配优先) |
\{n} | {n} | 恰好n个 |
\{-n,m} | {n,m}? | n个到m个(忽略优先) |
\{-} | *? | 0个或多个(忽略优先) |
\{-1,} | +? | 1个或多个(忽略优先) |
\{-,1} | ?? | 0个或1个(忽略优先) |
从上表中可见,vim的忽略优先量词不像perl的 *? +? ?? 那样,而是统一使用 {- 实现的。
这大概跟忽略优先量词不常用有关吧。
环视和固化分组
vim居然还支持环视和固化分组的功能,强大,赞一个 :D
关于环视的解释请参考Yurii的《精通正则表达式》一书吧。
vim | Perl | 意义 |
\@= | (?= | 顺序环视 |
\@! | (?! | 顺序否定环视 |
\@<= | (?<= | 逆序环视 |
\@<! | (?<! | 逆序否定环视 |
\@> | (?> | 固化分组 |
\%(atom\) | (?: | 非捕获型括号 |
和perl稍有不同的是,vim中的环视和固化分组的模式的位置与perl不同。
例如,查找紧跟在 foo 之后的 bar,perl将模式写在环视的括号内,
而vim将模式写在环视的元字符之前。
# Perl的写法
/(?<=foo)bar/
# vim的写法
/\(foo\)\@<=bar
参考
vim的帮助文件非常有用,关于正则表达式可以参考以下的内容。
:h pattern
:h magic
:h perl-patterns
(Read More)
Jun 18, 2008
最近Firefox的行为很奇怪,出现了许多以前一直没见过的现象。回想一下似乎是升级了delicious bookmarks 2.0.58版导致的。
目前发现的问题如下:
- 历史菜单内的前进、后退按钮失效,工具栏的前进、后退、刷新按钮失效,右键菜单中相应菜单也失效,但用快捷键和鼠标手势可以正常浏览;
- 不论访问什么网页,地址栏总是显示第一次手工输入的地址,而不会随着当前页面的变化而更新;
- Ctrl-Tab切换Tab时,松手后屏幕中间显示的切换菜单不会自动消失;
- 按一下Ctrl-Tab无法在所有Tab中依次切换,只能在当前Tab和上一个Tab之间切换;
- Ctrl-PageUp和Ctrl-PageDown的功能会反过来,即Ctrl-PageUp变成“下一个Tab”,而Ctrl-PageDown变成“上一个Tab”。
这些现象在禁用delicious bookmarks后消失。但delicious bookmarks又不能不用,于是卸载之后从官方插件站点上重新安装了一次,目前还未发生上述问题。
2008-6-20更新:
今天delicious bookmarks 2.0.64版发布了,更新内容包括:
This release fixes several issues with FF2 and FF3 GA.
- Fixes for “Organize Bookmarks” performance on FF3
- Fixes for strange tab behavior in FF2
- Fixes for sync issues on startup and login
- Removing status bar icons now frees up space on the status bar
- Classic mode has been simplified to remove the Delicious menu and work via bookmarklet interface
- Cleaned up Delicious Bookmarks Options UI
其中第二条就是解决标签切换行为异常的。
(Read More)
Jun 5, 2008
本文是日经BP上的一篇关于项目管理方法的实践的文章。对于短期的Web小型项目,
无论是开发周期、成本,还是技术上都有很大的风险。然而许多人对此认识不足,
导致项目失败,或是产品发布日期一拖再拖、成本大幅上升,或是匆忙发布后漏洞百出。
本文从项目管理的角度说明,即使在小型项目中,项目经理也不能将项目全权委托给技术主管,
而应当建立合适的体制,从几个方面对项目进行控制,这样才能保证项目的顺利进行。
原文在这里。
(Read More)
May 30, 2008
今天delicious上这个名为 SocialHistory 的脚本十分引人注目。
源代码可以在这里下载。
这段js代码的功能就是判断你的用户有没有访问过某个网站。使用方法很简单,例如:
window.onload = function() {
var sl = new SocialHistory();
alert(sl.doesVisit("Del.icio.us"));
}
如果用户曾经使用过del.icio.us,那么该函数就会返回真,否则返回假。
其实原理并不复杂,它利用了链接的 a:visited 伪类的属性。首先在页面上生成一个iframe,
并在这个iframe中设置 a 和 a:visited 为不同的样式。然后将网站的链接插入到 iframe 中。
浏览器就会根据用户的访问历史,为访问过的链接设置 a:visited 的样式。
最后再获得链接的最终样式,如果是 a:visited,就可以认为用户访问过该网站了。
具体的实现方式可以参考源代码。
这个脚本主要用于显示社会性书签的图标,可以恰到好处地显示用户所使用的网站。
但我担心,这样的做法是不是有盗取用户隐私之嫌?
虽然这个方法只能判断用户有无访问特定的网站,并不能无限制地得到所有访问历史。
(Read More)
May 29, 2008
哦……Perl真的是太博大精深了。尤其是它的One-Liner程序,每一行都是优美的杰作啊。
下面搜集了一些很有用的One-Liner。大部分资料来自于
这里、
这里、
这里。
(Read More)
Apr 19, 2008
fcicq最近在IPA上看到一篇安全相关的文章,
它的最末尾有个checklist,于是催我把它翻译了。前几天比较忙,周末没什么事儿了,就翻译一下吧。
原文的标题是如何让网站更安全。
这里仅翻译文章最后的一个checklist。
2008/4/20更新:fcicq倒是神速啊,马上就把具体的应用策略扔出来了 :D
参考:PHP 实践 Security Checklist
(Read More)
Mar 27, 2008
今天继续翻译代码布局的这一部分。有些很明显的条目,就不翻译了,看看代码就应该明白是什么意思。
(Read More)
Mar 19, 2008
margin和padding的意义相信大家都很清楚,可是在具体应用中,
到底应该使用哪一个,就比较难于判断了。
这篇文章
说得挺清楚的,在这里翻译一下,供参考。
何时应当使用margin
- 需要在border外侧添加空白时。
- 空白处不需要背景(色)时。
- 上下相连的两个盒子之间的空白,需要相互抵消时。如15px + 20px的margin,将得到20px的空白。
何时应当时用padding
- 需要在border内测添加空白时。
- 空白处需要背景(色)时。
- 上下相连的两个盒子之间的空白,希望等于两者之和时。如15px + 20px的padding,将得到35px的空白。
浏览器兼容性问题
在IE 5.x、IE6中,为float的盒子指定margin时,左侧margin可能会变成两倍的宽度。
通过改用padding或指定盒子为display:inline
可以解决。
(Read More)
Mar 17, 2008
今天在写代码时遇到一个很奇怪的问题。我写的这样一个函数:
sub parse {
my $self = shift;
my $header = shift;
my $charset = shift;
# 其它处理
# ...
}
至于如何调用,则是先通过 MIME::Parser 模块解析邮件,
然后调用解析结果中的 MIME::Head::get 函数来获得邮件头的值,
再将其结果传递给 parse 函数:
print $self->parse($head->get("Cc"), "GB2312");
通常都没有问题,在parse函数中,$header取到 Cc 邮件头,而 $charset 取到 “GB2312”;
但当一封邮件中不存在Cc时,就会出现一件怪事:
$header 变量竟然取到了第二个参数 “GB2312” 的值!
在 parse 中将 @_ 打出来,发现当Cc邮件头取不到时,第一个参数就“消失”了,
参数列表就变成了 (“GB2312”)。按照常理,参数列表应该是 (undef, “GB2312”)才对啊。
百思不得其解中,偶然看到 MIME::Head::get 的文档中这样说:
- If a numeric INDEX is given, returns the occurence at that index, or undef if not present:
- If no INDEX is given, but invoked in a scalar context, then INDEX simply defaults to 0:
- If no INDEX is given, and invoked in an array context, then all occurences of the field are returned:
上面的调用属于没有 INDEX 的情况,莫非parse函数的参数列表提供了一个列表环境,
导致MIME::Head::get返回了一个数组?
于是强制为它提供一个标量环境,结果就正常地得到了 (undef, “GB2312”)。
print $self->parse(scalar $head->get("Cc"), "GB2312");
看来果然是上下文环境造成的问题。parse函数的第一个参数期待一个常量,
而函数的参数列表却是一个列表环境,再加上MIME::Head::get在列表环境中返回数组,
这样就会导致两种错误:
- 如果不存在Cc,则参数列表为(“GB2312”),$header = “GB2312”;
- 如果存在多个Cc,则参数列表为(“Cc-val1”, “Cc-val2”, “Cc-val3”, “GB2312”), $charset=”Cc-val2”。
两种情况都十分荒谬。
对Perl的上下文不熟悉的人,这里可要特别注意啊。
(Read More)