大卡和小卡

大卡叫卡路里。小卡也叫卡路里。这个世道就是这么奇怪。明明差一千倍,却叫一样的名字。不信你去查字典,看 wiki。大卡用大写 C,小卡就用小写 c。所以以前我从来没有搞明白过,今天总算明白了。我们国家规定食品上的热量用千焦,也就是 kj(不知道这两个字母会不会被绿坝拦住),不过生活中谁也不会说我刚刚吃了多少多少千焦的东西,别扭。一般说吃了几百卡热量的东西,就是指大卡,也就是千卡。卡太小了,生活中用起来不方便,所以生活中说的都是大卡。比如跑步机上半小时消耗 400 卡就是说 400 大卡。但是吃的东西上面标 kj 就让我很不爽,干嘛不直接算好来个“你吃完这个就有530卡热量”的字样呢,还要我换算。不过还好,反正就是除以 4。因为一个大卡等于 4.182 千焦,这样一罐 250 ml 每 100 克 248 kj 的牛奶相当于 155 大卡。这么说来,今天中午走了 5.3 公里,大约是 423 卡,消耗掉三罐牛奶的样子,这样理解起来比较开心。明天继续走。

怎样写 pod 文档

我想说的不是 pod 文档的格式。有关格式的可以看 perldoc perlpod 或者阅读 fayland 很久以前写的《怎么写POD》

先说动机。偷懒是天性,是事物发展的源动力,是进化的产物。写程序本身就是搞个自动干活的傀儡来反复偷懒。所以写完程序没有文档在情在理。程序员还有一个常见的现象,喜欢推到重来。因为原来写得太复杂了,就算是以前自己写的,也不能当下一眼洞穿,还不如重写更舒服。有时候这是正确和必要的,叫重构,但大多时候并不需要。

但有文档就不同,它帮你回到过去。我经常在 search.cpan.org 上看模块的用法,然后照着例子用。我最近看很久以前写的东西,朦朦胧胧,七兜八拐,晕头转向。这种情况已经不止一次了,如果有个速查手册或者简单的帮助提示,于人于己都会方便不少。

敏捷开发不提倡写文档,因为要消耗时间和精力。但这不等于走向极端化说万万不要写文档。敏捷方式提倡开始时不写,因为需求还未定型。定了型的要写,但可以简单一点。这个是时机问题,也是优先级问题。就像写 Perl 模块,开始 alpha 版本的时候可以给一个实际用例,等接口都稳定下来了再写每个方法的用法。

下面简单快速列几点:

  • 文档是写给未来自己的情书。对自己好点~
  • 文档如同性,有高潮最好,就算一般也比没有强。
  • 现在写总比以后写更快更容易,不是吗?
  • 写还是不写,想想看自己是专业的还是业余的。
  • 集中写在末尾 __END__ 下面,用 vim 的 :vs 垂直分两屏,左边代码右边文档。
  • 随时 pod2html 阅读输出版本,像用户一样读和思考。
  • 读文档的人只关心怎么用,所以写文档的目的是告诉他们怎么用;如果关心实现细节,只管由他去看源代码好了。
  • 多举例子和实际的 use case。这最直观,也最容易学用。
  • 维护 FAQ。用的人都会问些什么问题,直接列出来问答。
  • 请人来读。读不懂的地方就是白写了,立即整改。
  • 还没写的要占个位子先。这样就算出去上趟厕所心都是定的。
  • 跑个测试检查文档覆盖率。看看还有哪些位子没占到。

Google Ads

Changes 文件中的时间戳怎么来的

显然不应该是看了表手工打出来的。如果是以前用 UltraEdit 之类工具的话,有个快捷键可以快速插入当前时间。Changes 文件里用的时间戳一般都是这样的格式:

Tue Nov 17 18:20:59 2009

现在用 vim 的话,道理也一样。先设置快捷键:

imap <F2> <C-R>=strftime("%c")<CR>

然后按 F2 就可以了。以上代码来自 c9sslides

如果要调用外部命令,比如打印这样的时间格式:

2009-11-17 18:33:32

可以这样设置:

imap <F2> <C-R>=system('perl -MClass::Date -e "print Class::Date::now"')<CR>

貌似这是我第一次正儿八经用快捷键映射,落伍了。

认知与表达

有时候心里的感受很特别,可就是说不出来道不明,无以言表,这是为什么?因为没有对应的词汇。词汇是什么?是对信息交流双方所达成共识的某一事物的指代。如果缺少这种具体的联系,词汇就不成为沟通信息的工具。

就好比晒过的被子有股太阳的味道,这是种什么味道呢?谁也说不上,既不香,也不臭,简单的说很特别,但又不同于香水味,大蒜味,狐臭味。于是只能从出处来说。你也闻过晒过太阳的被子的味道吧,我也闻过,好吧我说的就是这种味道。但很显然,你说的和我说的味道又可能有些不同。所以有限的词汇限定了对认知的表达,每个人的实际感受可能有差异,甚至很大。正所谓一花一世界。

所以心里的特别感受这种事情,很难找到对方可以摸得到看得到的具象来共同体会,讲不请道不明就不奇怪了。幸好还有比喻的修辞手法,用别的来借代转换,帮助理解。

小孩子还不会说话的时候就已经能体会别人的意思,直到足够多地建立起词汇和事物的映射关系后,才慢慢地开始说话。至于词汇的读音和拼写,具体形式如何都不重要,所以有了各式语言,包括方言。

所以倒过来看,要有丰富的表达能力,就必须多认知。读书看报看电影都是认知,所以很多作家在写出脍炙人口的作品前一定是饱读了很多各式各样的书籍和资料。喜欢王小波的读得多了写出来的也是王小波的味道。如果读得再广再深入些,杂糅起来就成了自己的风格。

你看,我啰哩啰嗦说了这么多,就是因为小时候看书不多,认知有限,所以表达有障碍。说得通俗点,语文没学好。

写读书笔记

现在学而时嘻之上的文章我几乎每篇必读,并且颇有受益。今天在路上读了关于读书笔记的文章(),颇有共鸣。

最近读过的一本书,就是用蓝色圆珠笔在上面乱涂乱写。以前我很注意保持书页平整干净,就算写也尽量用铅笔。上个月我刚想通,书是自己的,买纸书来看的目的就是可以随时记下一闪而过的各种只言片语,回过头来只需要看有颜色的部分。注记也无非是提纲挈领,点画出实质和因果关系,没有现成的就自己概括,用自己的话来说,甚至自己画上关系图。碰到有疑惑的或者有质疑的就把问题写下来。就算后面马上看到有相关的解释,这种注记也是必要的,它体现了思维的过程,以后 review 就一清二楚了。实际上,写注记等于是整理思维脉络。看别人怎么说是客观被动观察,自己说出来是主观能动表达,调动的是大脑里不同的工作机制和流程。hoho,说到这里,才意识到这就是为什么我能听懂英文却讲起来不地道的原因。

如果读完一本书,别人问起来说了些什么而答不清楚,这本书就等于没读。用不了多久就会依稀记得大致几个朦朦胧胧的画面。所以人们常说,如果你会教别人书中的知识,就说明你真的学会了。教就是系统整理知识再按照逻辑关系因果关系表述清楚的过程,这个过程需要强力阅读后思考很多为什么怎么会的问题,理清脉络把握重点之后,才能有先有后,有详有略地教别人。教的前提是在自己大脑里作笔记。写下来的就是备课提纲。

我承认我有迂腐的藏书习惯,很多没有系统看完只是摆在书架上。想到时间不够,又并非全都现在用得上,基本上用来翻翻查查。不过现在我喜欢涂写概括复述,然后扔掉这本书。一堆纸而已,无可留恋,谁需要送给谁。只要提起这本书,能如数家珍摆出其中的精华就行。

至于注记工具,Google Notebook 就很不错,我经常用来铺写零散的思绪,然后整理归纳,非常方便,只管集中注意力思考并打字记录下来。不过在纸上写字画图更快速更直观也更流畅,不容易打断思路。另外像 CPAN 网站若干年前推出一个 Annotated CPAN,帮大家对 CPAN 上 Perl 模块文档的每个段落(或者代码)加上旁注。这其实也是读书笔记,如果大家都来质疑就成了头脑风暴。就像强力研读中说的,是不是需要建个网站分享读书笔记呢?应该会很有用的。知识精华的快速传播和分享,推动起来意义非凡。

其实不光是读书,任何载体形式的内容都应该有这样一个概括归纳的过程。看强力研读的博客文章如是,看完就应该概括下,记下来,假设要再说给别人听。而写 blog 本身也是一个“读后感”,也是一个归纳思考的过程。

以往坏就坏在读书的读字上了,流于读的形式之后,就忘了读的目的和诉求。

三点式

三点式

今天是第 99 天,带孩子去拍百日照。之前诸多不顺,到最后顺利拍完,看到兜兜无邪的笑容,满心喜悦。

pod2html: no title for

用 pod2html 转以前写的模块,发现有些报这种错误:

pod2html: no title for /path/to/module.pm

一时半会儿 google 不到,问人也没碰到过。一番折半查找后,发现

=head1 NAME
 
Module::Name

这样的写法不规范,需要补上 ‘ – what is this’ 这样的简述:

=head1 NAME
 
Module::Name - Yet another perl module

小五结婚啦

小五结婚啦

小五的婚礼很特别,啤酒屋酒吧,黑啤畅饮,气氛热到不行。好久没有这么哈皮了。主人别出心裁地和大家合影拍一次成像照片,超有感觉。难忘的一刻。

RunKeeper

RunKeeper

试过几款 iPhone 上的跑步软件,都不太满意。有的根本没有数据出来,比如 321 Run;有的让人很无语,比如 Counch to 5k,到点提醒时发出刺耳的警报声,虽然应该可以设置,不过第一印象很坏,打到冷宫。

后来看到 ashchan 用 Nike Plus 传感器记录,也去转了一圈,没买到。之后无意间试了下这款 RunKeeper,还不错,界面粗陋但简洁,重要数据一目了然。关键是它会上传数据到 runkeeper.com 网站,在地图上标出线路,速度变化,高程变化,消耗的卡路里等等。此外它还会立即将跑步结果推到 Twitter 上去。在 Twitter 上搜索 #runkeeper 会看到其它用户的跑步记录,让人感觉一个人跑步也不孤单,仿佛他们从来都是不常谋面却心照不宣的朋友。

RunKeeper 有免费版和收费版,不过我觉得免费的够用了。我的跑步记录在这里

github backup

万事皆有可能,托管在 GitHub 上的仓库如果不备份,心里总不安。立即动手。

第一件事情是取得所有仓库列表。有了 API 就容易多了:

curl -s http://github.com/api/v2/yaml/repos/show/chunzi | grep ':url:' | awk -F/ '{print $NF}'

-s 表示 slient 模式,不输出下载进度。取来的数据是 yaml 格式,我只关心包含仓库名的 url 一行,grep 出来,打印路径最后一列,即仓库名称。

接下来写个简单脚本 github-backup,给定仓库名,如果从未备份过则 clone 裸仓库;否则下载更新。

#!/bin/bash
repo=$1
user=chunzi
url=git@github.com:$user
cd github
if [ ! -d $repo.git ]; then
    git clone --bare $url/$repo.git $repo.git
    cd $repo.git
    git remote add --mirror origin $url/$repo.git
    cd ..
else
    cd $repo.git
    echo `pwd`
    git remote update
    cd ..
fi

备份下来的仓库统一放在 ./github 目录下。用 --bare 克隆裸仓库,我不需要另行 check out 工作目录,仓库数据就已足够。然后用 git remote add 添加远程仓库以便以后增量更新。

如果目的只是单向备份下来,这里的 --mirror 选项可以不加,我试了下后续 git remote update 也能工作。

但是加了的话,应该表示本地仓库是远程的镜像,就是说,如果将新工作提交到这个本地裸仓库,就可以在此裸仓库中用 git push 将所有数据同步镜像到远程 GitHub 上。这一点我还没实践过,我现在只需要备份下来,不需要双向同步。

最后,写个简单的 Makefile,以后每次备份直接 make:

.PHONY: github
github:
        curl -s http://github.com/api/v2/yaml/repos/show/chunzi | grep ':url:' | awk -F/ '{print $$NF}' | xargs -I% bin/github-backup %

Makefile 中的 $ 需要转义,方法是用两个 $,因为 Makefile 自己也有一套 $ 开头的变量。

另外,如果 github 上删除了仓库或者改了名字,需要手工处理备份的仓库。备份 github 以外的 git 仓库也是一样的,稍改下代码。最后放到 crontab 里自动备份。