五月 21, 2008

Plug your own filter into Catalyst

Template::Manual::Filters里面提供了好多很好用的filter,当它们不够用的时候,还可以提供自己写的filter函数。但是怎么告诉Catalyst呢?没有找到文档,只好又去看代码。方法是在MyApp.pm里面__PACKAGE__->setup;一行之前添加如下代码:

__PACKAGE__->config( 'View::HTML' => {
    FILTERS => {
        'myown' => \&myown_filter,
    },
});

View::HTML换成你自己的View,然后写一个名为myown_filter的函数来完成真正的filter功能。

五月 18, 2008

Completing read

自动补全功能在任何时候都是受欢迎的,Emacs提供了一个基本的函数completing-read,可以在接受用户输入时提供补全功能。除此之外,我们还可以使用一些更加强大的函数,比如ido里面的ido-completing-read,或者使用iswitchb提供的功能。

使用ido-completing-read比较简单,参见psvn.el。而iswitchb并没有提供一个类似的函数,所以必须自己写一个。

(defun wl-completing-read (prompt choices dummy require-match)
  "Use iswitchb completion functionality."
  (let ((iswitchb-make-buflist-hook
         (lambda ()
           (setq iswitchb-temp-buflist choices))))
    (iswitchb-read-buffer prompt nil require-match)))

(defvar wl-completing-read-function
  (if (fboundp 'iswitchb-read-buffer) 'wl-completing-read 'completing-read))

在引入wl-completing-read-function变量之后,要使用funcall来调用它,而不是直接进行函数调用。

(funcall wl-completing-read-function prompt choice nil t)

五月 11, 2008

Authorization in Catalyst

一边看Jonathan Rockway的书——Catalyst,一边有模有样地学着写,到了authentication and authorization这部分被彻底打败了。

一开始按照书的去做,结果登录部分总是有问题(也可能是自己抄错了),于是去看文档,登录部分问题解决,认证部分又失败。无数次碰壁之后,没法子,只好去看代码,把Catalyst::Plugin::Authentication下面的代码看了个遍,终于搞明白了。有三种方法设计数据库,分别对应一个表、两个表和三个表。使用三个表的时候要使用Catalyst::Plugin::Authentication::Store::DBIC,其它两种情况要使用Catalyst::Plugin::Authentication::Store::DBIx::Class。这两个Store的配置方式也是不同的。所谓三个表,就是一个帐号密码表,一个角色(role)表,和一个关联表(记录每个帐号对应的角色);两个表即去掉角色表,而将其内容放在关联表里的角色部分;一个表最简单,将角色直接记录在帐号密码表里面,多个角色用逗号分割,记录在一个字段里。

我按照书上的例子建了三个表,却使用了错误的Store,自然得不到正确的角色信息。而不同的Store,还使用不同的方式验证用户登录,DBIC要用$c->login,而DBIx::Class要用$c->authenticate,要命的是传参的方式也不一样,前者接受用户名和密码两个参数,后者却接受Hash,要把用户名和密码对应字段名作为key传进去。这么多对应关系,有一点点错误,就完蛋了。

需要注意的是,文档里提到login函数不再提倡使用,只是为了兼容,才保留在哪里。由此可见,如果不是出书的速度慢了点,就是Catalyst的开发速度够快。所以,以后就不要使用三个表的设计了。

五月 07, 2008

Customize agenda view of Org Mode

看了Randy Pausch的Time Management,感觉有必要改善自己使用Org Mode的方式,First thing first。我常用的任务状态有四个——TODO, STARTED, WAITING, DONE。日积月累,处于WAITING状态的任务已经达到7个之多,TODO夹在里面,很难分辨。最佳的解决方法是重新安排任务日期,使其不再出现在每天的任务列表里面。然而总有些东西挥之不去。

我的第一个解决方法是降低这些任务的优先级,然后设置排序算法,使优先级低的任务出现在不显眼的位置,对我来说,就是列表的底部。

(setq org-agenda-sorting-strategy
  '((agenda priority-down time-up)
    (todo priority-down category-keep)
    (tags priority-down category-keep)))

其次,让WAITING这几个字符低调一点,红彤彤的一大片,太惹眼了。

(setq org-todo-keyword-faces
      '(("WAITING" . (:foreground "gray" :weight bold))))

这下世界清静了。

五月 04, 2008

Read CPAN module source code

有了cperl-perldoc,在Emacs里面看perl文档很方便,但有时候想看看代码,只好切换到命令行下面执行:

$ emacsclient --no-wait `perldoc -l A::Module`

如果使用下面的Emacs Lisp代码,可以省掉切换的麻烦,像使用cperl-perldoc看文档一样,直接在Emacs里面代开源代码文件。

(defun wl-cperl-find-module (module)
  "View source code of CPAN module."
  (interactive
   (list (let* ((default-module (cperl-word-at-point))
                (input (read-string
                        (format "CPAN module%s: "
                                (if (string= default-module "")
                                    ""
                                  (format " (default %s)" default-module))))))
           (if (string= input "")
               (if (string= default-module "")
                   (error "No module given")
                 default-module)
             input))))
  (let ((perldoc-output
         (with-temp-buffer
           (call-process "perldoc" nil t nil "-l" module)
           (buffer-substring-no-properties (point-min) (1- (point-max))))))
    (if (string-match "no documentation found" perldoc-output)
        (message "%s" perldoc-output)
      (find-file-other-window perldoc-output))))

(cperl-define-key (kbd "C-c m") 'wl-cperl-find-module)