自定义Firefox清除隐私对话框的默认值

Firefox的工具菜单中有个非常有用的功能:清除隐私数据,快捷键是Ctrl-Shift-Del。 经常做Web开发的人对这个功能一定非常熟悉,修改完一点代码看看效果时,都需要 Ctrl-Shift-Del然后按回车。

不过这个功能有个很郁闷的地方。Firefox 2中,默认是不清除网站登录信息的, 比如你登录了Gmail并选择下次无需输入密码,在Firefox 2中直接按Ctrl-Shift-Del再回车, 是不会清除Gmail上记忆的密码的。但是在Firefox 3中添加了一个很讨厌的选项, 清除“已通过验证的会话”,而且是默认选中的,这样直接Ctrl-Shift-Del再回车, Gmail上记住的密码也就没有了,下次进入Gmail还得再点一次登录。

幸好,通过about:config可以修改清除隐私数据对话框的默认值。 在地址栏中输入about:config,然后查找 privacy.item, 把 privacy.item.sessions 改为false就可以了。 这样再按 Ctrl-Shift-Del,“已通过验证的会话”选项就是默认不选中了。

(Read More)

[Perl]关于m//g的问题

今天讨论一下m//g一个的小问题。m//g表示在字符串中查找所有可能出现的模式匹配。 在标量环境下,m//g会依次查找每个出现的匹配。通常的用法是这样的:

while (/(pattern)/g) {
  print $1;    # 做些操作
}

在内部,m//g会保存一个“匹配位置”的变量,表示这次的m//g匹配到了什么位置,以便下次运行时从该处继续开始。 (这个位置可以通过pos函数获得,这里就不多说了。)通常,用在while循环里是没有任何问题的,但如果换成if会怎样?

$_ = "abc";
print "a" if /a/g;
print "b" if /b/g;
# 输出结果:ab

结果是正确的。如果将语句换个位置呢?

$_ = "abc";
print "b" if /b/g;
print "a" if /a/g;
# 输出结果:b

可见,第二次的模式 a 没有匹配。其实可以想到,第一次的m/b/g匹配后,匹配位置已经指向了字符串中的下一个位置c, 第二行的m/a/g继续从c开始匹配,当然不会匹配到任何东西。

借用一下《精通正则表达式》第7章对于Match运算符的说明:

匹配类型 尝试开始位置 匹配成功时的pos值 匹配失败时的pos值
m/.../ 字符串起始位置(忽略pos) 重置为undef 重置为undef
m/.../g 字符串的pos位置 匹配结束位置的偏移值 重置为undef
m/.../gc 字符串的pos位置 匹配结束位置的偏移值 不变

话说回来,在if中使用/g选项是毫无意义的。这里只是提个醒,当你遇到诡异的无法匹配的问题时,别忘了是不是在if中使用了m//g。

(Read More)

[Perl]管道、进程及其他

昨天一个同事问我关于Perl中的 -| 描述符的问题。 他的程序大概是这样的:

unless (open FH, "-|") {
  exec "foo bar";        # 用exec执行另一个程序
  exit;
}
while (<FH>) {
  ...
}
close FH;
$ret = $? >> 8;
if ($ret == 1) {
  ...
}
那么这里的 open FH, “- ” 是什么意思?$? » 8 又是什么意思?

(Read More)

[Perl]用XML::Simple解析XML文件

在Perl中解析XML的方法最常见的就是使用 XML::DOM 和 XML::Simple了。 XML::DOM过于庞大,而且解析结果是一个DOM树,操作也不方便。 对于小型且不复杂的XML文件,XML::DOM真是杀鸡用牛刀。 这时就轮到轻便的XML::Simple上场了。

XML::Simple如其名,真的很简单。假设XML内容如下:

<opt>
    <user login="grep" fullname="Gary R Epstein" />
    <user login="stty" fullname="Simon T Tyson" >
        <session pid="12345"/>
    </user>
    <text>This is a test.</text>
</opt>

那么只需这样写:

use XML::Simple;
use Data::Dumper;

$xml = XMLin('sample.xml');
print Dumper($xml);

就可以轻而易举地将XML解析成一个hash,然后用foreach依次处理即可。

(Read More)

[Perl]杂谈

开发中遇到的几点问题:

1. split的分隔符不能使用字符串,只能使用正则表达式。

用perl -de 1; 启动后做实验:

  DB<1> x split '\\', 'a\\b\\c'
Trailing \ in regex m/\/ at (eval 13)[/usr/lib/perl5/5.8/perl5db.pl:628] line 2.
  DB<2> x split '\\\\', 'a\\b\\c'
0  'a'
1  'b'
2  'c'
  DB<3> x split /\\/, 'a\\b\\c'
0  'a'
1  'b'
2  'c'

试图指定分隔符为反斜杠,但 ‘\’ 出错,原因是perl会将第一个参数(字符串)的值作为正则表达式来解释, 结果 ‘\’ 就变成了 /\/ ,显然这是错误的正则表达式。 正确的写法是 ‘\\’ 被解释成 /\/,或者直接写 /\/。

读了bkブログ的文章后发现, perl的split函数是忽略末尾的空元素的,想让它不忽略,必须加个参数-1:

  DB<38> x split /,/, 'a,b,,c,,'
0  'a'
1  'b'
2  ''
3  'c'
  DB<39> x split /,/, 'a,b,,c,,',-1
0  'a'
1  'b'
2  ''
3  'c'
4  ''
5  ''

更多内容请点开看。

(Read More)

[Perl]交互调试mod_perl

应该很多人都在为mod_perl的调试方法发愁吧。通常只能使用print,或者输出到syslog中, 但都需要猜测错误位置并添加相应的日志输出,然后重启服务器,刷新,看结果…… 虽然使用Apache::Reload能减少重启服务器的麻烦,但Apache::Reload用多了就会出错,而必须重启, 何况打日志总不像交互式调试器方便。

mod_perl的官方文档中写明了如何使用调试器来调试, 不过这个方法在RHEL4下似乎不太好用(自己编译mod_perl的同学就应该没这个问题)。 查看了一下,原来RHEL4自带的mod_perlmod_perl-1.99_16-4, 而在官方的mod_perl的下载页面上最高版本只有 1 系的 1.30 和2系的2.0.4,并没有所谓的1.99版。 看这个mod_perl-1.99的内容,应该是1系和2系的混合体吧。 Apache::DB这个包与mod_perl-1.99不兼容,于是就无法正常调试了。

(Read More)

[Perl]mod_perl下的BEGIN/END行为

这篇文章,对于能看懂的同学是非常非常重要的资料,对于看不懂的同学就一点用处都没有啦。

调查一下mod_perl下BEGIN/INIT/CHECK/END等块的行为如何?

测试程序,保存为life.cgi:

#!/usr/bin/perl

print "pid = $$\n";
print "Start main running here\n";

BEGIN   { print "BEGIN\n"; }
INIT    { print "INIT\n";  }
CHECK   { print "CHECK\n"; }
END     { print "END\n";   }

如果直接执行就是这样的:

$ ./life.cgi
BEGIN
CHECK
INIT
pid = 4610
Start main running here
END

不论执行多少次,结果都相同(除了每次的pid不同之外)。但如果放到mod_perl下,结果就完全不一样了。 先单进程启动(httpd -X),再从浏览器中访问,结果如下:

BEGIN
pid = 4557
Start main running here
END

刷新一次,结果是:

pid = 4557
Start main running here
END

可见,mod_perl下没有INIT和CHECK过程,只有BEGIN和END。其中END在每次请求时必然执行, 但BEGIN只有在进程刚创建后的第一次请求时才执行,以后的请求就不执行了。

如果你用了 Apache::Reload,那么可以修改一下life.cgi试试看,哪怕是一点小小的改动也行。 修改之后刷新,可以看到BEGIN又回来了,不过再刷一次就没有了。 所以Apache::Reload会在重新加载程序后再执行一遍BEGIN。

根据上述结论再引申一下,use = BEGIN { requre + import }, 可以推断,在同一进程下两次加载执行了use的页面,那么第二次的use是不起作用的。

(Read More)

[Perl]读取YAML文件

Perl对YAML的支持很好,著名的Plagger就是用YAML作为配置文件的。

在Perl中读取YAML文件也很简单。常用的模块就是YAML,这是个纯Perl的实现,速度慢,但可以跨平台运行。 如果追求运行速度而不在乎平台问题,可以使用YAML::Syck和YAML::XS,两者都是C语言的实现。 YAML::Syck的C语言部分基于libsyck,而YAML::XS的C语言部分基于libyaml。 两者相比,YAML::XS稍稍快一点,而且它精确地实现了YAML标准1.1版的内容。

(Read More)

闪烁和感光症

感光症癫痫(Photosensitive Epilepsy) 是一种罕见的癫痫症。高速闪烁的灯光、连续出现的图案、闪烁的视频,甚至树叶被风吹动时摇曳的影子都有可能会引起感光症发作。

感光症引起各国的重视,是由于1997年的口袋妖怪事件。 1997年12月16日,《口袋妖怪》第38话《电脑战士3D龙》在日本播出。该片为了表现电脑内部的爆炸效果, 而多次使用了红->蓝->红->蓝的高速颜色切换,导致日本全国约750名儿童被送往医院,其中150人需要住院治疗。 因此导致《口袋妖怪》被停播数月,恢复后,导致事故发生的主角“3D龙”也没能在电视中继续出现。

所以现在日本的动画片开头都会添加字幕,请观众在观看时远离屏幕,并打开室内灯光,以减少感光症发作的可能性。

而在2007年播放的一段2012年伦敦奥运会宣传片上,由于使用了闪烁效果,也导致了英国数人感光症发作。

下面这段视频就是被禁播的《电脑战士3D龙》。大家可以注意10:13、11:48、14:56、15:54和17:39的闪烁镜头。 不过,有感光症的读者还是不要看的好。

警告:以下视频包含强烈的闪烁,请在观看时自行承担一切责任。特别是有感光症癫痫史的读者请不要观看。

WARNING: The following video contains flicker effects. Please take responsibility yourself while watching. DO NOT watch if you have photosensitive epliepsy.

警告:下記のビデオに激しい光の点滅が含まれています。視聴は自己責任でお願いします。特に光過敏性症候群の方はプレイしないでください。

(Read More)

Apache报告No space left on device的解决办法

今天在开发时突然apache无法启动了。表现为,输入 httpd -X 后片刻自动退出, 同时在error_log中有如下内容:

[Fri Aug 15 10:54:31 2008] [emerg] (28)No space left on device: Couldn't create accept lock

df一下发现不是磁盘空间的问题。Google了一下就找到了解决方案,原来是系统的信号量(?)不够用了。 用以下命令可以查看所有的信号量:

# ipcs -s
______________________________ Semaphore Arrays ______________________________
key        semid      owner      perms      nsems
0x00000000 19234816   nobody    600        1
0x00000000 19267585   nobody    600        1
0x00000000 19300354   nobody    600        1
0x00000000 19398659   nobody    600        1
0x00000000 19431428   nobody    600        1
0x00000000 19464197   nobody    600        1
0x00000000 19562502   nobody    600        1

然后用这行命令删除所有的信号量即可:

ipcs -s | grep nobody | perl -lane 'print `ipcrm sem $F[1]`'

(Read More)