Python code auto complete in vim by ropevim

Posted by – 2009/12/12

ropevim introduce a one stop python code auto complete, auto import and other features to vim.
refs: http://rope.sourceforge.net/ropevim.html

I did this:

$ mkdir /home/liwen/install/rope
$ cd /home/liwen/install/rope
$ hg clone http://bitbucket.org/agr/rope/
$ cd rope
$ python setup.py install
$ cd ..
$ hg clone http://bitbucket.org/agr/ropevim/
$ cd ropevim
$ hg clone http://bitbucket.org/agr/ropemode/
$ mv ropemode/ropemode/* ropemode/
$ python setup.py install

And added some code in my .vimrc:


let $PYTHONPATH .= ":/home/liwen/install/rope/rope:/home/liwen/install/rope/ropevim"
source /home/liwen/install/rope/ropevim/ropevim.vim

let ropevim_codeassist_maxfixes=10
let ropevim_guess_project=1
let ropevim_vim_completion=1
let ropevim_enable_autoimport=1
let ropevim_extended_complete=1

function! CustomCodeAssistInsertMode()
    call RopeCodeAssistInsertMode()
    if pumvisible()
        return "\<C-L>\<Down>"
    else
        return ''
    endif
endfunction

function! TabWrapperComplete()
    let cursyn = synID(line('.'), col('.') - 1, 1)
    if pumvisible()
        return "\<C-Y>"
    endif
    if strpart(getline('.'), 0, col('.')-1) =~ '^\s*$' || cursyn != 0
        return "\<Tab>"
    else
        return "\<C-R>=CustomCodeAssistInsertMode()\<CR>"
    endif
endfunction

inoremap <buffer><silent><expr> <Tab> TabWrapperComplete()

Then auto complete should work automatically. But RopeRename not work, which will fill up my cpu, I think it’s ok for a beginning.

PS: hg is mercurial

Mozilla Prism的Defect

Posted by – 2009/03/18

昨天,3月17日,是比较不幸的一天。下午因某些原因我在Windows Live Mail里回复邮件,可以说是我写过的最长的邮件,而且此邮件充斥着我的真情实感。我有个习惯发出去的邮件在Sent目录检查一下。但我发现这封邮件发出去后内容为空。我就崩溃了。难道这封邮件设置了“禁止转发”?没记得email支持这样的功能,如果是某些脚本捣的鬼,浏览器也应该提示我。

我使用Mozilla Labs的Prism启动的Windows Live Mail。用其他浏览器(Firefox, Opera)实验了一下,发现这是一个defect。gg了也没有发现同样的case。后来任同学帮忙在Windows下试了一下也有同样的问题。

去了#prism的IRC,没有人响应,可能另一个半球的同学都在睡觉。于是我默默的file了一个defect

将Python程序编译并转换成Windows可执行程序

Posted by – 2009/03/10

因为要在桃园学校的电脑上安装rur-ple,Pockey和Fred翻译了主程序和前三节课程,rur-ple网站的win32安装包没法merge到一起。所以我重新打一个临时的包。

在编译和打包之前需要安装下面的包:

Python2.5
http://www.python.org/download/releases/

wxPython 2.6
http://www.wxpython.org/download.php#binaries
http://sourceforge.net/projects/wxpython/files/wxPython/2.6.4.0/wxPython2.6-win32-unicode-2.6.4.0-py25.exe/download

py2exe 0.6.5 – 第一个支持Python2.5的版本
http://www.py2exe.org/

编译程序

参照:http://effbot.org/zone/python-compile.htm

进入要编译的python文件所在目录如下。

D:\sunlw\projects\ygclub\teaching\rurple1.0rc3>python
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on
win32
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import compileall
>>> compileall.compile_dir(“./”, force=1)

编译完成后运行一下,确认正常。

D:\sunlw\projects\ygclub\teaching\rurple1.0rc3>rur_start.py

貌似运行起来快了一点。

将程序打包成exe

参照:http://www.py2exe.org/index.cgi/Tutorial
添加setup.py文件如下 (http://www.py2exe.org/index.cgi/Tutorial?action=AttachFile&do=view&target=setup.py)

from distutils.core import setup
import py2exe
setup(console=['rur_start.py'])

然后执行

D:\sunlw\projects\ygclub\teaching\rurple1.0rc3>python setup.py py2exe

运行exe程序试试

D:\sunlw\projects\ygclub\teaching\rurple1.0rc3>.\dist\rur_start.exe

成功。

安装包

另外我简单的将编译好的文件用7zip打成自解压程序。

注:
尽量保证依赖的库版本低一些,方便一些安装Windows 2000的电脑使用。

Linux教育笔记本

Posted by – 2009/03/08

先前在BLUG认识了pockey,了解到一些关于她所在团队Gdium的一些情况。于是去了一下他们的公司(也是BLUG的总部)聊了很多。3月7日,在众阳光志愿者Gdium团队的共同努力下,我们在朝阳区崔各庄实验学校(非公立,非政府承认)展开了一次教育笔记本体验活动(召集贴总结贴)。

总结如下:

有5个三年级的孩子,和4个的五年级的孩子参加了计划中的项目。

包括:
1) ”我明白了“ GCompris 数学、英文生词、打字、用鼠标等练习(初学者也可以应用的)
2) 一个关于地里的简单练习(就是在地图上找出国内不同城市的位置配对)
3)机器人游戏(输入简单的键来控制机器人的方向)
4)怎么用计算机录像 与 怎么用简单的绘画工具来绘画

不过能明显看出,孩子们最感兴趣的是电脑中的游戏,如泡泡龙。孩子天性嘛!
但我们应该让他们知道可以利用电脑做很多其他的事情。

值得一提的是,逻辑发展这个环节,虽然给定的机器人没有向右转的功能。
但大部分五年级的孩子都能很快的想到机器人“左转”三次就等于“右转”一次。
有的五年纪的孩子能理解给出的三个英文命令的中文意思:“前进“、“左转“和“停止“。
一个五年级的孩子最后成功的用程序画出了一个正方形。
然后这个孩子负责教了其他几个孩子写这个程序,还积极的演示给来参观的志愿者看。

pockey给三位崔各庄的老师介绍了“开放教育”的一系列内容。
随后这几位老师和pockey、浮游和fredthered等同学聊了好一阵子。
我觉得老师对这种体验活动都很接受和欢迎。

朱力安演示了一下教师终端控制学生电脑的功能。很好很强大~
播放了准备的用开源软件制作的动画片,投影到黑板上,孩子们很开心的以此为背景玩手影游戏。

去看了一下崔各庄的机房,比桃园学校好一些,机器多一些。刚配置的这匹二手电脑,看起来还不错。
据说还要安装网络。

最后几个孩子还问我们下周会不会来。我说回头来把今天用的软件拷给他们,或者装到学校的机器上让他们用。

现在已经确定下周六(2009年3月14日)在桃园学校再办一次体验活动,
番茄JJ建议之后在汇蕾学校也办一次。
因为崔各庄实验学校的校长今天不在,所以下周六还会再去一次崔各庄。

=====
一直以来大家在讨论Linux以及开源软件与我们所熟知的MS Windows世界的异同。很多朋友在尝试之后发现,从功能上确实可以互相替代,但最后因为习惯,游戏支持,办公软件或者因为企业部署成本的原因又回到Windows上。这种争论还会继续下去。
但从这次活动我们可以看到,对于孩子来说用什么软件不是很重要。他们也没怎么想过这是运行在什么操作系统上,运行的是什么软件,他们只看到了实质的内容:控制机器人,或者好玩的游戏。鼠标点击就可以开启一个游戏或者开启一个文字处理的界面。
先前还曾担心,让孩子们学习python编写的机器人小游戏(rur-ple),他们会觉着陌生乏味而没法继续下去。但实际的反应却超出预期。
对于孩子们的教育方式,我觉着还需要再想想,再调整。
不过无论如何,so fay so good!

在OpenSUSE11.1下使用WG111v3无线网卡

Posted by – 2009/03/05

我的USB无线网卡型号是NetGear WG111v3(芯片为RTL8187B),性能不错,长时间使用稍微有点热,但绝对可以接受。

之前一直在Ubuntu8.04下通过ndiswrapper+Windows驱动的方法使用。OpenSUSE11.1的Kernel是 2.6.27.7-9,这个版本内置了rtl8187的驱动。但是有defect,使用一段时间网速会变慢或者dhcp获得了ip却ping不通 router。

suse:/home/sunlw # uname -a
Linux suse 2.6.27.7-9-pae #1 SMP 2008-12-04 18:10:04 +0100 i686 i686 i386 GNU/Linux

我本想同样用ndiswrapper的方式解决,但没能成功。也许我使用方法不对,ndiswrapper的方式NetworkManager或者ifup的形式都找不到wlan0这个设备。

苦恼中发现了下面这个帖子:

http://www.susegeek.com/wireless/rtl8187b-wireless-native-driver-support-in-opensuse-111-kernel-2627/

有几个网友在抱怨与我类似的问题,三楼的网友给了一个linux-wireless邮件列表中的解决方案。

http://osdir.com/ml/linux-wireless/2009-01/msg00713.html

rtl8187驱动的维护者说,目前这个defect已经解决,但是需要几个月才能放入kernel的mainline,即使2.6.29也不会有这个补丁。

需要动手编译一下相关的modules。这个页面有详细说明,作者建议仔细阅读这个页面再进行下一步操作。

http://linuxwireless.org/en/users/Download

简单摘要如下:

到 compat-wireless-2.6的下载目录 http://wireless.kernel.org/download/compat-wireless-2.6/ 下载最新的包。这个包来自wireless-testing.git tree最新的版本,每天更新。(这个目录有防盗链,所以最好直接点击下载…)

然后,

解压缩

tar jxvf compat-wireless-$(date -I).tar.bz2

编译

cd compat-wireless-$(date -I)
make

安装

sudo make install

卸载之前的模块

sudo make unload

如果想卸载自己编译的版本

sudo make uninstall

因为我需要rtl8187这个模块,所以

modprobe rtl8187
lsmod | grep rtl8187

确认已经加载成功。重启。
使用”Yast2控制中心>网络设备>网络设置”重新进行无线网卡的设置。搞定!

因为compact-wireless-2.6不是mainline的版本所以

sunlw@suse:~/Desktop> dmesg | grep rtl
rtl8187: 8187B chip detected. Support is EXPERIMENTAL, and could damage your
phy0: hwaddr 00:1e:2a:af:14:0c, RTL8187BvE V0 + rtl8225z2
usbcore: registered new interface driver rtl8187

PS:OpenSUSE里NetworkManager和ifup形式的网络管理只能二选一,回头找一个network monitor放在panel里。

PS:我在Ubuntu下编译了整套的monodevelop,但是有点麻烦,需要逐个安装依赖,并逐个编译cil的wrapper包,然后才能编译一个功能较为完整的monodevelop。装一个OpenSUSE11.1是为了直接使用编译好的Unstable版。但好像最近也有for Debian的deb包了,不知道是不是于同步的。

PS: OpenSUSE下编译内核模块需要安装的工具有gcc, automake, autoconf, kernel-source, kernel-syms这些包在安装DVD中都有。
Have fun!

.NET类的成员变量初始化与构造函数执行的顺序

Posted by – 2009/02/05

.NET类的成员变量初始化与构造函数执行的顺序是怎样的呢?可以通过下面的测试得出。

namespace MSIL.Tests
{
    public class BaseType
    {
        string field = Helper.WriteLine("base type instance field");
        static string staticField = Helper.WriteLine("base type static field");
 
        static BaseType()
        {
            Console.WriteLine("base type cctor");
        }
 
        public BaseType()
        {
            Console.WriteLine("base type ctor");
        }
    }
 
    public class DerivedType : BaseType
    {
        string field = Helper.WriteLine("derived type instance field");
        static string staticField = Helper.WriteLine("derived type static field");
 
        static DerivedType()
        {
            Console.WriteLine("derived type cctor");
        }
 
        public DerivedType()
        {
            Console.WriteLine("derived type ctor");
        }
    }
 
    public class Helper
    {
        public static string WriteLine(string info)
        {
            Console.WriteLine(info);
            return info;
        }
    }
 
    [TestFixture]
    public class BaseTypeTestFixture
    {
        [Test]
        public void TestNewDerivedType()
        {
            var obj = new DerivedType();
        }
    }
}

在执行了TestNewDerivedType这个用例后会在输出中显示如下结果:

derived type static field
derived type cctor
derived type instance field
base type static field
base type cctor
base type instance field
base type ctor
derived type ctor

可以得出其顺序是:

  1. 派生类静态成员变量
  2. 派生类静态构造函数
  3. 派生类实例成员变量
  4. 基类静态成员变量
  5. 基类静态构造函数
  6. 基类实例成员变量
  7. 基类实例构造函数
  8. 派生类实例构造函数

实际上在这个过程中一直到System.Object的构造函数都会被执行。

另见
Essential .NET Volume 1: The Common Language Runtime Page 60 Types and Initialization

什么是PrivateImplementationDetails

Posted by – 2009/01/18

解析一个.NET程序集时发现了一段<PrivateImplementationDetails>{A_GUID}模样的代码,这是.NET编译器对某些指令做得优化,经分析会在如下情况下产生。

优化数组创建

var int1 = new[] { 1, 2, 3, 4, 5, 6 };

在解析上面的代码时,发现其产生了一些由编译器控制的IL代码

IL_0008:  ldc.i4.6
IL_0009:  newarr     [mscorlib]System.Int32
IL_000e:  dup
IL_000f:  ldtoken    field valuetype '<PrivateImplementationDetails>{393AE015-A550-4A61-9BFF-186AFB6A4D12}'/'__StaticArrayInitTypeSize=24' '<PrivateImplementationDetails>{393AE015-A550-4A61-9BFF-186AFB6A4D12}'::'$$method0x60000f8-1'
IL_0014:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0019:  stloc.0

如果没有使用初始化器

var int1 = new int[6];

生成的IL代码如下

IL_0008:  ldc.i4.6
IL_0009:  newarr     [mscorlib]System.Int32
IL_000e:  stloc.0

上面是创建值类型数组的情况,如果是引用类型的数组呢?

var obj1 = new object[3];
var obj2 = new[] {new object(), "test", 1};

生成的IL代码如下

IL_0001:  ldc.i4.3
IL_0002:  newarr     [mscorlib]System.Object
IL_0007:  stloc.0
IL_0008:  ldc.i4.3
IL_0009:  newarr     [mscorlib]System.Object
IL_000e:  stloc.2
IL_000f:  ldloc.2
IL_0010:  ldc.i4.0
IL_0011:  newobj     instance void [mscorlib]System.Object::.ctor()
IL_0016:  stelem.ref
IL_0017:  ldloc.2
IL_0018:  ldc.i4.1
IL_0019:  ldstr      "test"
IL_001e:  stelem.ref
IL_001f:  ldloc.2
IL_0020:  ldc.i4.2
IL_0021:  ldc.i4.1
IL_0022:  box        [mscorlib]System.Int32
IL_0027:  stelem.ref
IL_0028:  ldloc.2
IL_0029:  stloc.1

从下图可以看到,在产生的.NET程序集中有一个<PrivateImplementationDetails>开头的Module

PrivateImplementationDetails

<PrivateImplementationDetails>{0BAF451E-34D3-4B3B-8567-B578D84A6965}是这个编译器产生的Module的名字,{0BAF451E-34D3-4B3B-8567-B578D84A6965}是这个dll的MVID(Module Version Identifier)。

那么为什么要通过调用System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray这个静态方法来初始化数组呢?通过这位同学试验可以得出结论这是为提高效率而做出的编译时优化。

那什么情况下.NET编译器会产生PrivateImplementationDetails这种机制呢,我还没找到一个完整的列表。除数组外我还发现大的switch表也会产生PrivateImplementationDetails,并简单的试出了启用这种机制的case数量的临界值。

优化case比较多的switch

在代码中加入两个方法SwitchWith6Cases()和SwitchWith7Cases()

public void SwitchWith6Cases()
{
    var param = "a";
    switch (param)
    {
        case "a": break;
        case "b": break;
        case "c": break;
        case "d": break;
        case "e": break;
        case "f": break;
    }
}
 
public void SwitchWith7Cases()
{
    var param = "a";
    switch (param)
    {
        case "a": break;
        case "b": break;
        case "c": break;
        case "d": break;
        case "e": break;
        case "f": break;
        case "g": break;
    }
}

前者生成的代码如下,基本符合C#代码的逻辑

.method public hidebysig instance void  SwitchWith6Cases() cil managed
{
  // Code size       105 (0x69)
  .maxstack  2
  .locals init ([0] string param,
           [1] string CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldstr      "a"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ldloc.1
  IL_000a:  brfalse.s  IL_0068
  IL_000c:  ldloc.1
  IL_000d:  ldstr      "a"
  IL_0012:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_0017:  brtrue.s   IL_005c
  IL_0019:  ldloc.1
  IL_001a:  ldstr      "b"
  IL_001f:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_0024:  brtrue.s   IL_005e
  IL_0026:  ldloc.1
  IL_0027:  ldstr      "c"
  IL_002c:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_0031:  brtrue.s   IL_0060
  IL_0033:  ldloc.1
  IL_0034:  ldstr      "d"
  IL_0039:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_003e:  brtrue.s   IL_0062
  IL_0040:  ldloc.1
  IL_0041:  ldstr      "e"
  IL_0046:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_004b:  brtrue.s   IL_0064
  IL_004d:  ldloc.1
  IL_004e:  ldstr      "f"
  IL_0053:  call       bool [mscorlib]System.String::op_Equality(string, string)
  IL_0058:  brtrue.s   IL_0066
  IL_005a:  br.s       IL_0068
  IL_005c:  br.s       IL_0068
  IL_005e:  br.s       IL_0068
  IL_0060:  br.s       IL_0068
  IL_0062:  br.s       IL_0068
  IL_0064:  br.s       IL_0068
  IL_0066:  br.s       IL_0068
  IL_0068:  ret
} // end of method SwitchSample::SwitchWith6Cases

而当switch有超过6个case的时候,所生成的IL代码如下。

.method public hidebysig instance void  SwitchWith7Cases() cil managed
{
  // Code size       189 (0xbd)
  .maxstack  4
  .locals init ([0] string param,
           [1] string CS$4$0000,
           [2] int32 CS$0$0001)
  IL_0000:  nop
  IL_0001:  ldstr      "a"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ldloc.1
  IL_000a:  brfalse    IL_00bc
  IL_000f:  volatile.
  IL_0011:  ldsfld     class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{E6F6F304-0E96-4AD2-AF7A-7D08372A387B}'::'$$method0x60000fd-1'
  IL_0016:  brtrue.s   IL_0079
  IL_0018:  ldc.i4.7
  IL_0019:  newobj     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::.ctor(int32)
  IL_001e:  dup
  IL_001f:  ldstr      "a"
  IL_0024:  ldc.i4.0
  IL_0025:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_002a:  dup
  IL_002b:  ldstr      "b"
  IL_0030:  ldc.i4.1
  IL_0031:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_0036:  dup
  IL_0037:  ldstr      "c"
  IL_003c:  ldc.i4.2
  IL_003d:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_0042:  dup
  IL_0043:  ldstr      "d"
  IL_0048:  ldc.i4.3
  IL_0049:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_004e:  dup
  IL_004f:  ldstr      "e"
  IL_0054:  ldc.i4.4
  IL_0055:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_005a:  dup
  IL_005b:  ldstr      "f"
  IL_0060:  ldc.i4.5
  IL_0061:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_0066:  dup
  IL_0067:  ldstr      "g"
  IL_006c:  ldc.i4.6
  IL_006d:  call       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::Add(!0, !1)
  IL_0072:  volatile.
  IL_0074:  stsfld     class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{E6F6F304-0E96-4AD2-AF7A-7D08372A387B}'::'$$method0x60000fd-1'
  IL_0079:  volatile.
  IL_007b:  ldsfld     class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{E6F6F304-0E96-4AD2-AF7A-7D08372A387B}'::'$$method0x60000fd-1'
  IL_0080:  ldloc.1
  IL_0081:  ldloca.s   CS$0$0001
  IL_0083:  call       instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
                                                                                                                        !1&)
  IL_0088:  brfalse.s  IL_00bc
  IL_008a:  ldloc.2
  IL_008b:  switch     ( 
                        IL_00ae,
                        IL_00b0,
                        IL_00b2,
                        IL_00b4,
                        IL_00b6,
                        IL_00b8,
                        IL_00ba)
  IL_00ac:  br.s       IL_00bc
  IL_00ae:  br.s       IL_00bc
  IL_00b0:  br.s       IL_00bc
  IL_00b2:  br.s       IL_00bc
  IL_00b4:  br.s       IL_00bc
  IL_00b6:  br.s       IL_00bc
  IL_00b8:  br.s       IL_00bc
  IL_00ba:  br.s       IL_00bc
  IL_00bc:  ret
} // end of method SwitchSample::SwitchWith7Cases

这时候在<PrivateImplementationDetails>*模块中会有如下的一个叫做$$method0×60000fd-1的静态字段,辅助switch的case匹配。

.field static assembly class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '$$method0x60000fd-1'

通过Dictionary<string,int32>::TryGetValue方法去查找匹配的case。O(1)的效率在case多的情况下比线性O(n)的查找快的多。

A Conversation with Anders Hejlsberg, by Bill Venners with Bruce Eckel(August 4, 2003)

Posted by – 2009/01/05

A Conversation with Anders Hejlsberg,
by Bill Venners with Bruce Eckel
August 4, 2003

These conversation includes 8 parts:

  • In Part I: The C# Design Process, Hejlsberg discusses the process used by the team that designed C#, and the relative merits of usability studies and good taste in language design.
  • In Part II: The Trouble with Checked Exceptions, Hejlsberg discusses versionability and scalability issues with checked exceptions.
  • In Part III: Delegates, Components, and Simplexity, Hejlsberg discusses delegates and C#’s first class treatment of component concepts.
  • In Part IV: Versioning, Virtual, and Override, Hejlsberg explains why C# instance methods are non-virtual by default and why programmers must explicitly indicate an override.
  • In Part V: Contracts and Interoperability, Hejlsberg discusses DLL hell and interface contracts, strong names, and the importance of interoperability.
  • In Part VI: Inappropriate Abstractions, Hejlsberg and other members of the C# team discuss the trouble with distributed systems infrastructures that attempt to make the network transparent, and object-relational mappings that attempt to make the database invisible.
  • In Part VII: Generics in C#, Java, and C++, Hejlsberg compares C#’s generics implementation to Java generics and C++ templates, describes constraints in C# generics, and describes typing as a dial.
  • In Part VIII: CLR Design Choices, Hejlsberg discusses IL instructions, non-virtual methods, unsafe code, value types, and immutables.
  • 从Google Docs发布到Wordpress

    Posted by – 2008/12/26

    之前我在Google Docs里维护了几篇技术文档,正想迁移到Wordpress里来。Google Docs原生支持Blogger,按照其一贯作风,也应该直接或间接的支持其他应用。果然,可以通过xmlrpc的方式支持发布到Wordpress

    用Freemind做会议记录,并导出成Wikipedia格式

    Posted by – 2008/12/26

    1. Compile a minutes in freemind like the structure below.

    2. You can format your mind map with a default fancy theme (just like the picture
    above)

    Format > Automatic Layout

    3. Export your mind map to a mediawiki markup format.

    File > Export > Using XSLT…

    Choose the XSL file in the attachment, and the export file path.

    Then click Export.

    4. Copy the text in the file on your export file path to the editor on mediawiki. Like
    below.

    5. Click Show Preview button to see if the page is correct and polish it accordingly.

    Limitation:

    We only support plain text node in freemind.

    Download:

    http://code.google.com/p/zhimaowan/
    Download directly

    Good luck!