上次说到 hexdump 指定二进制文件格式以及打印的方式不好用,所以用 Go 写了一个替代,起名叫 bprint (想不到更好的名字了)。代码以及使用说明都在 github 上。这个工具跟 hexdump 的 format string 最大的差别在于把二进制文件格式和打印方式分开来指定,个人觉得这种方式使用起来更加方便。
Go 的确是个不错的语言,标准库很多函数的接口设计得很好用。说下写这个小工具时的一点感受吧。
写这个程序时要处理二进制文件。Go 是强类型的,没法像 C 一样读一块内存以后随便当成各种类型的整数,必须用 encoding.binary 这个库提供的函数来读取各种类型的整数。这一点使得 bprint 的性能肯定没法跟 C 版本的相比。
另一方面强类型使得 Go printf 一类函数的 format string 不需要指定整数大小,有符号无符号整数可以使用相同的字符指代,因为这些信息从参数的类型里可以直接得到。Go 的 printf 类函数用起来很舒服。
标准库的正则表达式用起来也还算方便(当然还是没法跟 Ruby 这样内建正则表达式支持的语言相比),其 API 命名很有意思也很值得学习。用来做字符串匹配的函数名匹配于下面这个正则表达式:
Find(All)?(String)?(Submatch)?(Index)?
String 表示函数接受 string 类型的参数,没有这个名字的接受 []byte 为参数
Submatch 表示返回值是否包含匹配的各个 group
Index 则表示返回匹配内容还是返回匹配项的起止索引
All 表示是否返回所有匹配内容
这种命名方式使得我们看函数名就能知道函数的用途,所以很容易找到自己需要的函数。(这让我想起 Joel Spolsky 的文章 Making Wrong Code Look Wrong 里提到的正确的匈牙利命名法。)貌似标准库的正则表达式是把 Russ Cox 的 RE2 用 Go 重新实现了一遍,有空的时候想看下它的代码。
另外 flag 库用来做命令行选项的解析真是比 C 的 getopt 好用太多。
Go 没有 exception,类似 C 通过返回值来表示错误,不过由于有 multi return value,所以 Go 使用这种方式比 C 方便一些。这种错误处理的方式的确会使代码看起来不那么干净,但不会带来 exception 的问题。(Exception 本质上是一种 non-local goto,其存在的问题可以看 Raymond Chen 的文章 Cleaner, more elegant, and harder to recognize)。
go 这个工具使得我们可以不用写 Makefile,自动格式化代码,方便的编写和执行测试,这些特性都使得我们可以更加专注于写代码而不用跟编译构建系统做斗争。go 这个工具的存在让我体会到了下面这句话的含义
“Go is not meant to innovate programming theory. It’s meant to innovate programming practice.” — Samuel Tesla
Go 的确是一个很好的 C 的替代,目前性能还不是非常好,但相信未来随着编译器的进步会有提升。暂时还没有用到 Go concurrency 的特性,但看起来也是很诱人。
如果对 Go 有兴趣,想知道 Rob Pike, Ken Thompson 还有 Robert Griesemer 为什么发明 Go 以及 Go 的设计思想,推荐 Rob Pike 的文章 Less is exponentially more。
Google Plus 我很少用,但是 +1 我觉得还是一个不错的功能。以前看到不错的页面会存书签,后来发现这些书签平时不会用到,想搜东西的时候一来不会去搜书签,二来书签不包含内容也搜不到。而 +1 过的页面以后再次 Google 的时候会更容易找到,可以很方便的用来
mark 自己觉得有价值的网页。(Twitter 的 search 太差。Evernote 的 webclip 不错,不过比起单击一下就能 mark 还是麻烦了一点。所以只有非常有价值的内容我才会用 webclip。)
最近网络环境非常糟糕,无法访问 Google 的情况越来越多。实验室的公用代理经常无法使用,不得不在本地写几个 PAC 文件备用。使用过程中发现用本地的 PAC 文件设定代理
Chrome, Firefox, Twitter For Mac 都能正常使用,唯独 Safari 不行。但是一旦本地开一个 web server 来获取这个文件就一切正常。
Google 一番得到结果,原因是 OS X Lion 的 sandbox 机制限制了 Safari 能够访问的文件,而我指定的 PAC 文件 Safari 没有权限读取。
;; Copyright (c) 2008 Apple Inc. All Rights reserved.;;;; sshd - profile for privilege separated children;;;; WARNING: The sandbox rules in this file currently constitute;; Apple System Private Interface and are subject to change at any time and;; without notice.;;(version1)(denydefault)(allowfile-chroot)(allowfile-read-metadata(literal"/var"))(allowsysctl-read)(allowmach-per-user-lookup)(allowmach-lookup(global-name"com.apple.system.notification_center")(global-name"com.apple.system.logger"))
vardirect='DIRECT';varhttp_proxy='PROXY host:port; DIRECT';varblocked_list=["akamai.net","akamaihd.net"];varblocked={};for(vari=0;i<blocked_list.length;i+=1){blocked[blocked_list[i]]=true;}functionhost2domain(host){vardotpos=host.lastIndexOf(".");if(dotpos===-1)returnhost;// Find the second last dotdotpos=host.lastIndexOf(".",dotpos-1);if(dotpos===-1)returnhost;returnhost.substring(dotpos+1);};functionFindProxyForURL(url,host){returnblocked[host2domain(host)]?http_proxy:direct;};
ruby-debug-base19 version 0.11.25 does not work with ruby 1.9.3-p0 on OS X.
I found a workaround on WyeWorks Blog.
Here’s my modified gist to install the
working version with RVM managed ruby-1.9.3-p0
I’m taking the SaaS class. The class
project can be done using the pre-created VirtualBox image or on Amazon EC2
virtual machine, but I want to do it directly on my Mac because its more
convenient for me. Luckily, there is
instructions on how to
configure a bare VM.
Looking into the configure script
used to configure the ubuntu VM shows that there is nothing special in the
software used. It just needs some ruby gems, PostgreSQL, and Sphinx. (The script
will also install and configure Vim, Emacs, but that’s not relevant to me.)
Configuring the environment on OS X should be easy, if you are not using Xcode
4.3.