[PBP]代码布局(3)
继续翻译Perl最佳实践的2.9~2.12。
最近遇到的一个任务是要将散落在系统各个文件中的 use lib '/opt/mysoft/lib'
; 这样的绝对路径引用改成相对路径,
以便整个系统能够轻易地移动到其他的目录中。系统是工作在Apache2 + mod_perl 下的,cgi程序位于 /opt/mysoft/cgi-bin 下。
初看起来似乎很容易:
use lib '../lib'; # 错误!
但实际尝试一下就会发现,这里的 ‘..’ 似乎找错了位置。当前目录并不是cgi程序所在的 /opt/mysoft/cgi-bin。
经过一番实验后,发现在 use lib
时,当前目录居然是在 / 下!这样这条路就走不通了。
另一个想法是通过 $0
获取到CGI程序的路径,再根据此路径来找到 lib 目录不就可以了么?
$dir = dirname $0;
use lib "$dir/../lib"; # 错误!
print "$_\n" for @INC;
实际运行就会发现,这一招也行不通。原因是use lib是在编译时执行的。编译时代码并没有被执行,
因此 $dir
变量为空(甚至都不存在),于是就成了 use lib "/../lib"
,当然不正确了。
这样看来 use lib
似乎必须要书写完整路径了。
CPAN文档的解释如下:
lib - manipulate @INC at compile time
实际上 use lib
可以理解为 BEGIN { unshift @INC, '/opt/mysoft/lib'; }
。
BEGIN段的内容在这一段编译结束后立即执行。
回到本来的问题上,如何能避免在系统中使用绝对路径? 其实使用mod_perl的功能一次性地指定好@INC,那么在CGI和pm模块中就无需再use lib了。
在mod_perl的官方文档中有关于如何调整@INC的说明。
一种方法是在 startup.pl 中书写完整路径:
use lib '/opt/mysoft/lib';
另一种方法是直接在httpd.conf中修改@INC
:
PerlSwitches -I/opt/mysoft/lib
这样虽然不能完全避免绝对路径,但至少在产品代码中可以不再使用 use lib 了。
同样地,use 也是在编译时执行的。(参考)use Module;相当于 BEGIN { require Module; Module->import( LIST ); }
程序代码中的所有use指令都会在代码执行前被执行,因此use不论放在哪里,效果都是一样的。因此 if ($use_first_lib) { use FirstLib; … } else { use SecondLib; … }
这样的代码是毫无用处的,不论$use_first_lib的值如何,FirstLib和SecondLib都会被加载。
最近发现gentoo下pidgin经常会不能输入,表现在输入法切换不出来,甚至无法输入英文字母。没办法只能重启pidgin。不过今天突然发现了问题的所在。那就是,从聊天窗口用Alt-Tab键切换到好友列表窗口,再用Alt-Tab切换回来,这时一切键盘输入就都不管用了。解决方法也很简单:再用Alt-Tab切换一次,就行了。另外为避免出现这种情况,建议没事儿时把好友列表窗口关掉。
前几天的这篇文章被 fcicq同学挑毛病,建议不要使用内核自带的ntfs, 而是使用ntfs-3g+fuse。查了一下,ntfs-3g可以完美支持ntfs分区的读写操作, 的确要比内核自带的ntfs好得多。
试试看。安装方法不难,直接emerge即可,它会自动安装 sys-fs/fuse:
# emerge ntfs-3g
我用的是gentoo 2007.0,内核版本2.6.23-gentoo-r8,还需要编译内核的FUSE支持:
# cd /usr/src/linux
# make menuconfig
勾选 File systems ---> <M> Filesystem in Userspace support
# make modules_install
# modprobe fuse
之后当然可以再打开 /etc/modules.autoload.d/kernel-2.6,把fuse加进去。
然后就可以mount ntfs分区了:
# mount -t ntfs-3g -o locale=zh_CN.UTF-8,silent /dev/sda6 /mnt/wine
进入分区后试试读写,均没有问题。
后来看了看ntfs-3g的官方主页的FAQ, 发现竟然允许大小写不同的同名文件,还有特殊字符(如\、?等Windows中不允许的字符)。 作者的理由是NTFS支持POSIX风格的文件名,也支持DOS、Windows格式的文件名, 为保持最大的兼容性,ntfs-3g就选择了POSIX——所以就出现上面这种现象了。 尝试者建立 ABC、abc、ab?c、abc\d等文件,均建立成功,重新启动到windows下试图打开这几个文件, 结果出现了问题:ABC正常打开,但一旦保存,ABC就会丢失,只剩下abc(因为同名),估计有可能需要chkdsk了; ab?c、abc\d文件无法保存、改名和删除。只能回到linux下面操作。
看来作者又是一个十足的协议派……为保险起见,还是先ro吧。
最后的/etc/fstab为:
/dev/sda6 /mnt/wine ntfs-3g auto,ro,locale=zh_CN.UTF-8,silent 0 0
今天在配置nvidia的显卡时出现了一个很头疼的问题。
按照官方网站上的文章, 一步步地顺利地安装好了显卡驱动:
# 先配置内核,详情参考官方文档,省略
# USE=gtk emerge nvidia-drivers
# modprobe nvidia
# update-modules
# eselect opengl set nvidia
# 然后修改xorg.conf,略
# startx
结果startx时出现了这样的错误:
Backtrace:
0: X(xf86SigHandler+0x84) [0x80cca34]
1: [0xffffe420]
2: X(main+0x2af) [0x807067f]
3: /lib/libc.so.6(__libc_start_main+0xd8) [0xb7db5838]
4: X(FontFileCompleteXLFD+0xa1) [0x806fb81]
Fatal server error:
Caught signal 11. Server aborting
查了半天资料未得到结果,后来想起我曾经安装过nVidia官方网站提供的驱动, 会不会是和portage的驱动冲突呢?于是卸载掉官方驱动:
# sh NVIDIA-Linux-x86-169.09-pkg1.run --uninstall
然后重新emerge:
# emerge nvidia-drivers
这样就可以顺利地启动X了。
首先安装前端 scim:
# emerge scim
常见的日文输入法是服务器/客户端模型的,Canna就不错(可内嵌在SCIM中)。安装方法也很简单:
# emerge canna
# /etc/init.d/canna start
# rc-update add canna default
然后安装scim的Canna支持:
# emerge scim-canna
最后启动scim,从输入法语言中选择日语即可。
注意:当初我认为要装FreeWnn,装上后发现关机时老是死掉,查了半天发现原来是 /etc/init.d/freewnn stop时死掉了。 后来发现不要freewnn也能正常输入日文。
最近重新安装了一遍gentoo,发现第一次安装时好多调查过的经验都没有记录下来,这次还得重新去找,麻烦…… 记下来供下次安装时使用吧。
按照手册上安装时,按照以下方法设置网卡(/etc/conf.d/net):
config_eth0=( "192.168.0.2 netmask 255.255.255.0 brd 192.168.0.255" )
routes_eth0=( "default via 192.168.0.1" )
dns_servers_eth0=( "DNS1的IP地址" "DNS2的IP地址" )
chroot之后首先上ccache以提高编译速度:
# emerge ccache
然后编辑 /etc/make.conf 加上:
FEATURES="ccache parallel-fetch"
CCACHE_SIZE="2G"
接下来安装必要的软件:
# emerge vim
升级portage:
# emerge portage
编译内核时别忘了打开framebuffer(高分辨率命令行用),还有Device Drivers->Sound->Advanced Linux Sound Architecture(声音驱动,参考 这里)。 当然也别忘了在 PCI Devices中选择你声卡的型号。
如果你使用SATA硬盘,注意设置grub.conf时别弄错了硬盘编号。
如何mount Windows XP的硬盘分区:首先保证内核中编译了ntfs支持,然后参考下面的结果来写mount参数:
/dev/sda6 on /mnt/wine type ntfs (ro,noexec,nosuid,nodev,nls=utf8,umask=0)
/dev/sda5 on /mnt/wind type vfat (ro,noexec,nosuid,nodev,codepage=936,iocharset=utf8,umask=0)
重新起动后安装xorg,修改make.conf:
USE="alsa bash-completion bzip2 gtk jpeg opengl ruby xscreensaver X -gnome -ipv6 -kde -qt3 -qt4"
INPUT_DEVICES="keyboard mouse"
VIDEO_CARDS="nvidia"
然后运行:
# emerge xorg-x11
装好后运行 xorgconfig 配置图形界面:
# xorgconfig
接下来是xfce4。修改/etc/make.conf:
LINGUAS="zh_CN ja" # for xfdesktop
然后:
# emerge xfce4
还有中文输入法:
# emerge scim scim-pinyin
安装好后退回普通用户,编辑.xinitrc设置启动xfce4:
exec scim &
exec startxfce4
最后别忘了将语言设置为中文:
$ vi .bashrc
export LANG=zh_CN.UTF-8
启动之后应该能看到小老鼠的桌面,按Ctrl+Space应该能出输入法了。
装firefox:
# emerge mozilla-firefox
# emerge netscape-flash
装完后自己上网找插件去。
另外,Firefox默认安装之后,在快速滚动滚轮时页面会沿着历史记录前进/后退,十分不爽。 在about:config将mousewheel.horizscroll.withnokey.action改成0即可解决该问题。
即时通讯,使用pidgin,基于gtk,支持GTalk和MSN:
# emerge pidgin
默认的字体比较难看,从微软那里借用一些过来吧。
# emerge mkfontdir mkfontscale
# mkdir /mnt/winc
# mount -t vfat /dev/sda1 /mnt/winc
# cd /mnt/winc/windows/Fonts
# mkdir /usr/share/fonts/TTF
# cp sim* msgothic.ttc msmincho.ttc msyh* meiryo* verdana* tahoma* /usr/share/fonts/TTF
# cd /usr/share/fonts/TTF
# mkfontdir
# mkfontscale
然后重启xfce4后即可设置字体。
另外,在编译xfwm4时加上USE=xcomposite,即可打开窗口混色开关,这样就可以在窗口管理器中设置窗口的透明度了。 另外 http://www.xfce-look.org/ 这个网站不错,可以下载到许多xfce4用的主题。
时钟有可能会不正确,可以修改 /etc/conf.d/clock,将 CLOCK=”UTC” 改成 CLOCK=”local”。
板载AC97声卡的配置,参考官方文档即可。
安装mplayer:
USE="aac cddb dvd encode gif mmxext mp2 mp3 png \
quicktime rar real samba srt vorbis \
win32codecs x264 xv xvid" emerge mplayer
安装Open Office:
# LINGUAS="zh_CN" emerge openoffice-bin
最近一直在忙点私活,又好久没写blog了,再不写点的话二月份就又要以单篇文章结束了。 前一阵子一直在研究Unicode,索性把研究结果介绍一下吧。
可能大家都听说过 Unicode、UCS-2、UTF-8 等等词汇,但它们具体是什么意思, 是什么原理,之间有什么关系,恐怕就很少有人明白了。 下面就分别介绍一下它们。
这个东西应该是很老很老很老了,不过很奇怪在国内为什么没几个人知道呢?虽然跟本blog的主题——技术——没有太大的关系,但因为实在是太常用了,就在这里贴一下吧。
原文来自Jorma Oksanen’s Origami,版权为非商用免费,但作者要求写出他的名字。另外本文的图和说明文字来自这里:A4用紙1枚で2枚収納できるCDケースをつくる。这篇文章要比原文说明得详细一些。