﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-qiezi的学习园地</title><link>http://www.cppblog.com/cpunion/</link><description>AS/C/C++/D/Java/JS/Python/Ruby</description><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 13:29:32 GMT</lastBuildDate><pubDate>Thu, 16 Apr 2026 13:29:32 GMT</pubDate><ttl>60</ttl><item><title>搬家</title><link>http://www.cppblog.com/cpunion/archive/2006/10/09/13499.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 09 Oct 2006 14:33:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/09/13499.html</guid><description><![CDATA[因兴趣转移，最近比较迷ruby和d，为了不再影响这里的c++氛围，搬到http://qiezi.javaeye.com。<img src ="http://www.cppblog.com/cpunion/aggbug/13499.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-09 22:33 <a href="http://www.cppblog.com/cpunion/archive/2006/10/09/13499.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>段落文本渲染引擎</title><link>http://www.cppblog.com/cpunion/archive/2006/10/09/13484.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 09 Oct 2006 03:44:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/09/13484.html</guid><description><![CDATA[最近在一个项目中要渲染段落文本，找了很多文字渲染库，发现都不能满足我的要求，所以只能自己做。字体渲染还是找freetype完成吧，虽然小字号效果不好，不过可以生成大图再缩小来解决掉，自己写一个字体渲染引擎也是不可望也不可及的事。<br /><br />有了freetype实现底层字体渲染，我只需要处理一些布局方法即可，其中要实现的有以下几点：<br /><br />1、英、中字体<br />很多中文字体中的英文字体都比较难看，所以在X的字体配置中设置了一个字体顺序。我也可以学学，传递一个字体列表，拿到一个字符时，按顺序从字体列表中查询，查询不到时就查下一个字体，这样就可以实现英、中使用不同字体了。<br /><br />2、分行<br />段落分行要考虑到中、英文不同的分割方式，还有标点符号，某引起标点符号不能在行尾（比如“&lt;等），某些标点不能在行首（比如”&gt;），某些标点不能分割（比如破折号），所以实际上要有一个分割算法，把段落分成一个个的标记，汉字直接分割，英文按空格分割，不能在行首的标点就分到前面单词里，不能在行尾的就分在后面的单词里。<br /><br />3、对齐<br />对齐方式有左、中、右、两端(Full Justification)这几种方式，目前大部分开源渲染库都不支持两端对齐，这也是我要自己实现的主要原因。左、中、右只要计算出一行的所有字符宽度，再计算出左边距即可。两端对齐则需要计算每个单词的间距。<br /><br />4、段首缩进<br />
原来设想在分段后直接加上全角空格，不想这个空格在转成UNICODE编码时，它的编码是\u0000，不能获取到全角空格的宽度。于是把它设成字体高度，看了一下效果还好。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13484.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-09 11:44 <a href="http://www.cppblog.com/cpunion/archive/2006/10/09/13484.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] D语言数组</title><link>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 07 Oct 2006 08:21:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</guid><description><![CDATA[先看一段代码：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br /><br />它输出结果如下：<br /><br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D19FB0, B7D19FB4,<br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,<br /><br />可以看到前3行地址相同，后面一行地址不同。为什么？<br /><br />D语言的数组分配是内存紧凑的，当减小数组长度减小时，只需要修改切片大小而不需要重新分配。当长度变大时，也会检查原来的缓冲区是否够大，以确定是否需要重新分配空间。注意第2次操作时把长度恢复为原来大小时，并非真的恢复了原来的状态，后面长出来的元素会被初始化为默认值。<br /><br />再来看一个：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> c;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br />在执行int[] d = c;以后，d的确是和c共享了存储区。不过在改变d的长度以后，它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用，它实际上创建了一个新的数组对象，但并不拷贝数组元素，它和int[] d = c[0 .. length]是等价的，都是数组切片操作。<br /><br />这个问题让我困惑不已。比如你用char[]表示一个单词，用char[][]表示一行，char[][][]表示多行。如何引用这个单词？你当然可以每次使用lines[i][j]，但如果处理步骤很多，这会不会看起来很头大？<br /><br />看上去应该这样使用：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][][] lines;<br /></span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][] line </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> lines[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">];<br />line.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> line.length </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />line[length </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;</span></div><br />可惜根据前面的结论，这将无法影响到lines。如果找不到一个引用类型指向数组，有时候使用起来还真是很麻烦。看起来把Line/Word包装成类是个勉强凑合的主意。。。<img src ="http://www.cppblog.com/cpunion/aggbug/13418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-07 16:21 <a href="http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] Array slicing</title><link>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 06 Oct 2006 01:35:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</guid><description><![CDATA[数组slicing操作并不复制数据。<br /><br />指针的slicing操作和数组slicing语意是相同的。<br /><br />通过slicing生成D数组，比原来直接使用指针的好处是可以有边界检查。<br /><br />最近刚好犯了这个错误，在使用freetype时，render出来的位图数据直接使用slicing生成数组保存起来。由于slicing并不复制数据，这样后面的render操作会覆盖前面的数据，所以我保存的数组其实都指向同一个缓冲区。当释放face对象时，缓冲区也没了，再访问恐怕要段错误了。<br /><br />这个是D文档中明确描述了的，我却花了点时间才排除这个错误，写下来记录之～<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-06 09:35 <a href="http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.168发布</title><link>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 05 Oct 2006 01:23:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</guid><description><![CDATA[新特性：<br />1、给委托增加ptr属性，指向委托所绑定的对象。<br />这是一个语法糖，dg.ptr被转化为cast(void*)dg，它只能作右值，所以除了能读取它以外，在语法上禁止对它赋值。要想把委托绑定到不同的对象，你只能自己实现：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br /><br />    alias </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() DG;<br />    DG dg </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)).bar;<br /><br />    Foo[</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">] foos;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i, inout Foo foo; foos){<br />        foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(i);<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(Foo foo; foos){<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)foo;<br />        dg();<br />    }<br />}</span></div><br />这种方式也不是我们所希望的，一般来说委托绑定到多个对象时，因为是取到某成员函数指针，再进行绑定。比如模拟一个ActiveSupport所扩展的一个ruby.Array#map用法：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Array(T){<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br />    T[] data;<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(T[] data){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.data </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> data[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> .. length];<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> map(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> function() func){<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() dg;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> func;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />        </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(T v; data){<br />            </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)v;<br />            dg();<br />        }<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    auto arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Array</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(Foo)([</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">)]);<br />    arr.map(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">Foo.bar);<br />}</span></div><br />是的，delegate内部保存了2个指针，所以我们可以容易地hack它。<br /><br />[注：上面的main函数中数组直接量赋给栈对象也是这个版本中新增的内容，显然只能用于static对象是很鸡肋的。这里简单带过不提。]<br /><br />[注：上面这个map的模拟并不是ActiveSupport的map扩展的全部用途，那个map还是收集返回值，这里只演示调用语法。ActiveSupport中扩展的map调用语法是map(&amp;:to_s)，就可以收集到数组中所有元素调用to_s后的返回值。]<br /><br />2、给内嵌内的实例增加outer属性，指向外层对象。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Outer{<br />    </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Inner{}<br /><br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        Inner inner </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Inner;<br />        inner.outer.foo();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    Outer outer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Outer;<br />}</span></div><br />这个特性可能应用并不是很广吧。<br /><br />3、mixin多个析构函数。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">template A(){<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />    }<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">A::~A()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br />template B(){<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">B::~B()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> C{<br />    mixin A;<br />    mixin B;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    C c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> C;<br />    delete c;<br />}</span></div><br />这些析构函数会和mixin相反的顺序执行。我不明白的是，为什么不让mixin多个构造函数？为何不让这些构造函数晚于被mixin的类（上面的C类）的构造函数，并按mixin进来的顺序执行？<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-05 09:23 <a href="http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[private] 文字绘图库资料收集</title><link>http://www.cppblog.com/cpunion/archive/2006/09/28/13124.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 28 Sep 2006 12:03:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/28/13124.html</guid><description><![CDATA[主要收集可以绘制文字的绘图库。<br /><br />一、imagemagick:<br />http://www.cit.gu.edu.au/~anthony/graphics/imagick6/<br />可以绘制文字，不过中文好像不能自动断行。<br /><br />二、vips<br />http://vips.sourceforge.net<br />使用pango绘制文字，中文可以断行，缺少2端对齐功能。自己修改代码增加了调整行距功能，做成ruby扩展库，amd64上使用失败，原因待查。<br /><br />三、freetype<br />http://vips.sourceforge.net<br />不依赖其它图形/窗口库，其它不熟悉，待查。<br /><br />四、Graphite<br />跨平台的字体渲染库。待查。<br /><br /><br />搜寻已有数月，目前看到的几个库都不太理想，mac osx上可能比较专业，不过集成较困难。<br /><br />苹果网站上的比较完整的字体绘制和布局方面的资料：<br />http://developer.apple.com/documentation/Carbon/Conceptual/ATSUI_Concepts/index.html<br />其中布局方面的专业知识：<br />http://developer.apple.com/documentation/Carbon/Conceptual/ATSUI_Concepts/atsui_chap3/chapter_3_section_3.html#//apple_ref/doc/uid/TP30000029-TPXREF157<br /><br /><br />其它资料：<br /><ul><li><a href="http://anonymouse.org/cgi-bin/anon-www.cgi/http://en.wikipedia.org/wiki/Uniscribe" title="Uniscribe">Uniscribe</a> (Windows multilingual text rendering engine)</li><li><a href="http://anonymouse.org/cgi-bin/anon-www.cgi/http://en.wikipedia.org/wiki/WorldScript" title="WorldScript">WorldScript</a> (Old Macintosh multilingual text rendering engine)</li><li><a href="http://anonymouse.org/cgi-bin/anon-www.cgi/http://en.wikipedia.org/wiki/Apple_Type_Services_for_Unicode_Imaging" title="Apple Type Services for Unicode Imaging">Apple Type Services for Unicode Imaging</a> (New Macintosh multilingual text rendering engine)</li></ul><br /><img src ="http://www.cppblog.com/cpunion/aggbug/13124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-28 20:03 <a href="http://www.cppblog.com/cpunion/archive/2006/09/28/13124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Linux] linux使用流水帐</title><link>http://www.cppblog.com/cpunion/archive/2006/09/22/12843.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 22 Sep 2006 12:45:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/22/12843.html</guid><description><![CDATA[6年前安装过linux，当时只是好玩而已，当时的linux对我来说可玩性太低，差不多都是装了耍几天酷就卸掉了。<br /><br />2年前被迫使用linux作开发平台，使用的是fedora core 2，感觉一般。后来去掉图形界面运行服务器程序，开发主要还是在windows上，有需要时putty连上去操作。<br /><br />其后1年多，安装过suse, ubuntu，还有许多记不得名字的发行版，感觉并不好，ubuntu的界面主题给我印象比较深。<br /><br />半年前正式开始在同事的鼓吹下试用gentoo，才发现这个安装最麻烦的发行版使用起来却是最舒服的，特别是对于开发者来说。你能想到的语言、库，基本上都可以直接在里面emerge到，而且总能保持最新版本，特别适合开发人员。<br /><br />不过对于gentoo系统不熟悉，也走了不少弯路。网上的linux资料相当多，当然有很大一部分也是相当老，往往你照着某资料配置半天，才发现它已经过时了。最头疼的是界面美化，我想要的是一个至少看得过去的界面，不影响网页浏览。看着网上大堆的教程，不胜其烦，一直没搞懂。其间在ubuntu、suse和gentoo之间摇摆了几次，后来因为suse占用资源太多，被我抛弃。<br /><br />这时候已经对windows有点烦，又在rails的带动下安装了mac osx，同时还安装了ubuntu和gentoo。mac osx下除了textmate这个编辑器还有点吸引力以外，其它部分就没多少吸引我的了，命令行让我烦恼不已。在linux下可以rm aa -rf或rm -rf aa来删除一个文件，在mac osx下必须使用后一种形式，自由惯了突然受到约束，感觉真是不爽。<br /><br />保留ubuntu主要是因为它可以完美支持我的笔记本上所有硬件，声音控制面板也支持，不过对于开发人员来说，安装点开发包还真是麻烦，升级也比较慢。其实后来才发现gentoo对硬件支持一点也不差，只是不会使用而已。<br /><br />最近gentoo 2006.1发布，安装以后就一直在使用它，除了界面粗体字和无线网络没解决以外，倒也没什么问题。前几天突然开窍，搞懂了所有软件安装前都看看USE标志需求，把整个系统升级了一下，重新编译内核再安装无线驱动，一切都很顺利，界面粗体字竟然自己出来了，只是浏览器里面没有粗体。网上找了一下，原来因为我安装的是bin版本，中文支持都没有，于是设置LINGUAS，emerge安装源码版本，终于搞定。就这个小问题让我折腾了半年，真是惭愧。接下来同样设置USE搞定vlc图形界面、SCIM，realplayer也没有以前那个段错误，pgadmin也好了，还发现ubuntu里面的realplayer放不出来的一些电影可以在这里面放出来，vlc+realplayer基本上可以搞定所有视频格式了。感觉一切都美好起来，终于明白gentoo里面USE是最重要的，以前把它当成个可选项了，安装软件以前最好emerge -av一下看看有哪些USE需求。要早明白这个，也不用安装得这么辛苦了。<br /><br />接着在邮件列表中一些朋友的帮助下，安装了gnome-volumn-manager，放入光盘就能自动mount，按退出键也能自动umount并弹出，和windows下一样方便了，连移动硬盘和ipod也能很好支持。唯一遗憾是图形化的无线网络配置工具还没有安装上，虽然通过脚本也可以配置，但毕竟不是那么方便。开源社区最近几年在易用性上下足了工夫，gentoo也有庞大的开发社区，想必解决这个也不用多久了。<br /><br />用过很多发行版，gentoo是我用得最辛苦的一个，却也是用得最顺心的一个。<br /><br />贴点桌面抓图：<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot.png" /><br /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-1.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-2.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-3.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-4.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-5.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-6.png" /><br /><br /><img src="http://www.cppblog.com/images/cppblog_com/cpunion/63/o_Screenshot-7.png" /><img src ="http://www.cppblog.com/cpunion/aggbug/12843.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-22 20:45 <a href="http://www.cppblog.com/cpunion/archive/2006/09/22/12843.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.167发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 19 Sep 2006 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</guid><description><![CDATA[这个版本实现了计划已久的数组直接量。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  {<br />    static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static float[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [1f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static char[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">1</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">2</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">3</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">4</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">5</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />}</span></div><br />数组类型由第1个元素类型决定，类型不匹配将会产生编译错误。<br /><br />接着是多维数组：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [[</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">]];<br />  </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">; arr){<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">){<br />      writefln(i);<br />    }<br />  }<br />}</span></div><br /><br />另一个特性是更强的typedef。原有的typedef强类型在某些情况下会产生混乱。<br /><br />下面的代码摘自 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&amp;group=digitalmars.D.bugs&amp;artnum=3843<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int1;<br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int2;<br /><br />void show(Int1 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int1: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(Int2 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int2: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">int: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> i);<br />}<br /><br />void show(long l) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">long: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> l);<br />}<br /><br />void main() {<br />     Int1 value1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">42</span><span style="color: rgb(0, 0, 0);">;<br />     Int2 value2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">69</span><span style="color: rgb(0, 0, 0);">;<br /><br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     long l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">23</span><span style="color: rgb(0, 0, 0);">;<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> l);<br />     show(l </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     short s </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">105</span><span style="color: rgb(0, 0, 0);">;<br />     show(s </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> s);<br />}</span></div><br />如上面代码所示。typedef定义出来的类型和原有类型的相同形式重载函数可以共存，这可以完成更强类型的重载，C＋＋的重载还不能实现这个。<br /><br />这个强类型的typedef好像原本就支持，大概是运算结果类型比较模糊。<br /><br />好处是显页易见的。比如有一个Time和TimeInterval类型，它用来表示绝对时间或相对时间间隔；另有一个输出函数用来显示结果。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">string;<br /><br />typedef long </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">;<br />typedef long TimeInterval;<br /><br />void output(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Time: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void output(TimeInterval t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Interval: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void main(){<br />  </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  TimeInterval interval </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(TimeInterval)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  output(</span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);">);<br />  output(interval);<br />}</span></div><br />是的，使用上麻烦了很多，因为我们试图用一个数值类型去表示多个矢量类型。<br /><br />这里Time time = cast(Time)100不再只是100这个简单的数值，它还携带了Time这个类型。TimeInterval interval = cast(TimeInterval)100也不只是100这个数值，我们给它赋予了时间间隔的含义。<br /><br />还可以想像得更开阔一些，用它定义时间、长度、面积、加速度、速度、温度等，重载一些计算函数（可惜D还不支持全局操作符重载），这样就方便完成一些物理量的运算了，而且类型得到检查，速度加一个整数值结果还是速度，速度乘时间得到的是长度，时间减时间得到的是时间间隔，速度加时间将产生编译错误。。。。。。神奇的是这些类型可能都是一些简单类型，我相信它至少可以保证运行效率不会太低。当然你用C＋＋类也可以完成这些，并且利用编译器优化让它的效率保持最高，甚至内联的结果就是简单类型的运算，我还是更愿意使用这简单的类型来typedef。当然这可能需要写大量重复的函数重载形式，没有关系，我想使用模板和mixin应该可以简化这一过程，而且会有相当多的家伙们愿意使用这种麻烦的形式来获得更“正确”的编译检查。<br /><br /><br />所以说，D语言的typedef的意义其实就是实现了矢量类型。<br /><br /><hr size="2" width="100%" /><br />又多想了一点。<br /><br />强类型要，语法糖也应该要。是不是可以借鉴一下ruby的语法，实现这种调用呢？<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">Length</span><span style="color: rgb(0, 0, 0);"> l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">cm;<br />l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">m;<br /></span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">now;<br />TimeInterval i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">hours;</span></div><br />免去了一些初始化的麻烦。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/12721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-19 20:16 <a href="http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[RoR] Post/Get分派</title><link>http://www.cppblog.com/cpunion/archive/2006/09/17/12571.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sun, 17 Sep 2006 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/17/12571.html</guid><description><![CDATA[<b>一、前言</b>
		<br />
		<br />出于数据安全性考虑，某些破坏性链接应该使用post请求，比如一个删除记录的请求。<br /><br />除了脚本确认以外，服务端还需要post验证，因为脚本是可以绕过的。想像你的页面上有一个删除链接，只作了客户端脚本确认（老的scaffold生成代码有这问题），被google找到了，它一个请求就会让你的数据丢失。<br /><br />rails对于这类请求的处理，是通过verify方法，默认的scaffold生成代码有如下内容：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">  verify </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">method </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">only </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> [ </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">destroy</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">create</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">update ]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"><br />         </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">redirect_to </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">list }</span></div><br />只有post请求时，destroy才会被允许，如果是get，就会被重定向到list。<br /><br /><b>二、实现</b><br /><br />我自己实现了一个method_dispatch，当请求一个/test/a时，如果是get，则会直接执行TestController#a；如果是post，则会执行TestController#a_post，a_post应该是protected，这样不会直接暴露给客户，get/post就严格区分开来了。<br /><br />method_dispatch现在是直接实现在ApplicationController中的，代码如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class ApplicationController </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ActionController</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">Base<br />  protected<br />  def self</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">method_dispatch(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">methods)<br />    before_filter </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">do_method_dispatch</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">only </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> methods</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">flatten</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">map</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">&amp;:</span><span style="color: rgb(0, 0, 0);">to_sym)<br />  end<br /><br />  private<br />  def do_method_dispatch<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> request</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">post</span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);"> respond_to</span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">#{action_name}_post</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">)<br />      </span><span style="color: rgb(0, 0, 255);">eval</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">#{action_name}_post</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">)<br />      </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> false<br />    end<br />  end<br />end</span></div><br />由于ApplicationController里面的方法会被子类继承到，所以必须严格处理访问级别。<br /><br />使用如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class TestController </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ApplicationController<br />  method_dispatch </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">a<br /><br />  def </span><span style="color: rgb(0, 0, 255);">index</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  def a<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">get a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />  def b<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">get b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />  protected<br />  def a_post<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">post a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />  def b_post<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">post b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />end</span></div><br />注意a_post，b_post要被保护起来防止直接调用。<br /><br />index.rhtml里面演示了使用get和post的情况：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Get a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">%&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> {</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">a</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">}</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> {</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> true} </span><span style="color: rgb(0, 0, 0);">%&gt;&lt;</span><span style="color: rgb(0, 0, 0);">br </span><span style="color: rgb(0, 0, 0);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Get b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">%&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> {</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">b</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">}</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> {</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> true} </span><span style="color: rgb(0, 0, 0);">%&gt;&lt;</span><span style="color: rgb(0, 0, 0);">br </span><span style="color: rgb(0, 0, 0);">/&gt;</span></div><br />rails在处理有:post =&gt; true参数的link_to时，生成的代码如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">a </span><span style="color: rgb(255, 0, 0);">href</span><span style="color: rgb(0, 0, 255);">="/test/a"</span><span style="color: rgb(255, 0, 0);"> onclick</span><span style="color: rgb(0, 0, 255);">="var f = document.createElement('form'); <br />       this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();return false;"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">Post a</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">a</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><br />经测试上面代码工作情况良好，使用get访问/test/a时，显示get a；使用post访问时，显示post a。使用get访问/test/b时，显示get b；使用post时，显示get b，因为b并没有使用method_dispatch。<br /><br /><b>三、应用</b><br /><br />下面的posts_controller.rb是scaffold生成的：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class PostsController </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ApplicationController<br />  def </span><span style="color: rgb(0, 0, 255);">index</span><span style="color: rgb(0, 0, 0);"><br />    list<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">  verify </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">method </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">only </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> [ </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">destroy</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">create</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">update ]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"><br />         </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">redirect_to </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">list }<br /><br />  def list<br />    </span><span style="color: rgb(128, 0, 128);">@post_pages</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@posts</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> paginate </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">posts</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">per_page </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">10</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  def show<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />  end<br /><br />  def new<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">new<br />  end<br /><br />  def create<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">new(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post])<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">save<br />      flash[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">notice] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post was successfully created.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />      redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />      render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">new</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    end<br />  end<br /><br />  def edit<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />  end<br /><br />  def update<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">update_attributes(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post])<br />      flash[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">notice] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post was successfully updated.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />      redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">show</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />      render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">edit</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    end<br />  end<br /><br />  def destroy<br />    Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">destroy<br />    redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />end</span></div><br />可以看到，它添加了verify，但action过多，需要在verify中维护一份对应方法名，稍不留神就容易出现漏洞。<br /><br />我把它修改如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class PostsController </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ApplicationController<br />  method_dispatch </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">new</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">edit</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">destroy<br /><br />  def </span><span style="color: rgb(0, 0, 255);">index</span><span style="color: rgb(0, 0, 0);"><br />    list<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  def list<br />    </span><span style="color: rgb(128, 0, 128);">@post_pages</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@posts</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> paginate </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">posts</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">per_page </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">10</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  def show<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />  end<br /><br />  def new<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">new<br />  end<br /><br />  def edit<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />  end<br /><br />  def destroy<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">inline </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;-</span><span style="color: rgb(0, 0, 0);">EOS<br />      Are you sure?<br />      </span><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Yes</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> {}</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> true </span><span style="color: rgb(0, 0, 0);">%&gt;</span><span style="color: rgb(0, 0, 0);"><br />      </span><span style="color: rgb(0, 0, 0);">&lt;%=</span><span style="color: rgb(0, 0, 0);"> link_to </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">No</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">edit</span><span style="color: rgb(0, 0, 0); font-weight: bold;">', :id =&gt; params[:id]</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">%&gt;</span><span style="color: rgb(0, 0, 0);"><br />    EOS<br />  end<br /><br />  protected<br />  def destroy_post<br />    Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">destroy<br />    redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br />  def edit_post<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">update_attributes(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post])<br />      flash[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">notice] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post was successfully updated.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />      redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">show</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />      render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">edit</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    end<br />  end<br />  def new_post<br />    </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">new(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">post])<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@post</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">save<br />      flash[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">notice] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Post was successfully created.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />      redirect_to </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">list</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />      render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">action </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">new</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />    end<br />  end<br />end</span></div><br />相应地，还需要把new.rhtml中的action从create修改到new，把edit.rhtml中的action从update修改到edit。<br /><br />这样的修改把必须使用post请求的action隐藏起来，而相应的get操作是不修改或删除记录的，如果以post请求，才会自动调用这些保护的方法。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/12571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-17 11:13 <a href="http://www.cppblog.com/cpunion/archive/2006/09/17/12571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Ruby] Ruby AOP</title><link>http://www.cppblog.com/cpunion/archive/2006/09/16/12539.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 16 Sep 2006 01:46:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/16/12539.html</guid><description><![CDATA[昨天在答一个问题时，看题不清答错了，不过却让我花了点时间想如何实现简单的AOP。<br /><br />在其它语言里实现AOP的确比较麻烦，java要用到动态proxy，如果是C＋＋，除了从源码上修改还真没好办法，aspectc就是这么做的。那么ruby里面如何实现呢？<br /><br />由于ruby是动态脚本语言，运行期可以把一个方法改名，也可以构造一个字符串动态生成方法，那么实现这个就不是难事了。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">module ExecuteBefore<br />  def self</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">included(base)<br />    base</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">extend(ClassMethods)<br />  end<br /><br />  module ClassMethods<br />    def execute_before(before_method</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">methods)<br />      methods</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">flatten</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">map</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">&amp;:</span><span style="color: rgb(0, 0, 0);">to_sym)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">each</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">method</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"><br />        alias_method </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">#{method}_old</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">to_sym</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> method<br />        class_eval </span><span style="color: rgb(0, 0, 0);">&lt;&lt;-</span><span style="color: rgb(0, 0, 0);">eval_end<br />          def </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">{method}(*args)<br />            #{before_method}(*args)<br />            #{method}_old(*args)</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">          end<br />        eval_end<br />      end<br />    end<br />  end<br />end<br /></span></div><br />使用时只需要在类里面include这个模块就行了，相当于mixin的功能。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class TestController </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ApplicationController<br /><br />  def </span><span style="color: rgb(0, 0, 255);">index</span><span style="color: rgb(0, 0, 0);"><br />    a(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br />    b(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">)<br />    c(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">)<br />    render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">hello</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  protected<br />  def </span><span style="color: rgb(0, 0, 255);">log</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">args)<br />    puts </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">log: #{args.map(&amp;:to_s).join(', ')}</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"><br />  end<br /><br />  def a(a)<br />  end<br /><br />  def b(a</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">b)<br />  end<br /><br />  def c(a</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">b</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">c)<br />  end<br /><br />  include ExecuteBefore<br />  execute_before </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">log</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">b</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">c<br />end</span></div><br />注意，由于使用execute_before时后面几个方法必须要有定义，所以必须放在后面，否则就会出错。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/12539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-16 09:46 <a href="http://www.cppblog.com/cpunion/archive/2006/09/16/12539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[RoR] Rails unittest一个小bug</title><link>http://www.cppblog.com/cpunion/archive/2006/09/16/12536.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 16 Sep 2006 01:32:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/16/12536.html</guid><description><![CDATA[之前为了省事，数据库配置如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">development_pgsql</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"><br />  adapter</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> postgresql<br />  database</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> myproject_development<br />  username</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> postgres<br />  password</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> <br /><br />development_mysql</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"><br />  adapter</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> mysql<br />  database</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> myproject_development<br />  username</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> root<br />  password</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> <br /><br />development</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"><br />  development_mysql<br /><br />test</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"><br />  adapter</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> postgresql<br />  database</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> myproject_test<br />  username</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> postgres<br />  password</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> <br /><br />production</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"><br />  development</span></div><br />正常运行没什么问题。后来发现在运行rake test作单元测试时会报错，把拷贝过来就没有问题。不过rubyonrails.com上不允许匿名提交bug，还真麻烦。<br /><br />另外发现config.active_record.schema_format = :ruby配置下，postgresql的timestamp字段默认值current_timestamp不能正确复制到数据库。经检查它是使用db:schema:dump复制下数据库模式，再使用db:schema:load生成测试数据库模式的，这个模块为了各数据库统一，会去掉那些不一致的默认值。解决办法是设置config.active_record.schema_format = :sql。<img src ="http://www.cppblog.com/cpunion/aggbug/12536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-16 09:32 <a href="http://www.cppblog.com/cpunion/archive/2006/09/16/12536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习备忘</title><link>http://www.cppblog.com/cpunion/archive/2006/09/07/12122.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 07 Sep 2006 06:24:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/07/12122.html</guid><description><![CDATA[发现不写备忘真是个坏习惯，很多准备好要学的东西有时就忘了。。<br /><br />语言：<br />haskell, lisp 函数式编程语言，受cookoo鼓舞开始学习haskell，加上haskell是实现pugs的语言，看来学一下也是应该的。lisp有时间也要看看，就当是折磨自己罢。。<br />erlang 分布式编程语言，已有应用OpenPoker,作者<strong><a href="http://lkcn.net/eubbs/index.php?showuser=9503">神宗冥浩</a>，简介 http://blog.mylkcn.net/senzung.php<br />prolog <br /><br />感觉面向对象以后的语言就没什么想象力了。。<br /><br />项目：<br />osian on dsource.org<br />ddl on dsource.org<br /><br /></strong><br />FP相关论坛：<br /><a href="http://agiletao.com/thread.php?fid=31">http://agiletao.com/thread.php?fid=31</a><br /><a href="http://ocaml.cn/">http://ocaml.cn/</a><img src ="http://www.cppblog.com/cpunion/aggbug/12122.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-07 14:24 <a href="http://www.cppblog.com/cpunion/archive/2006/09/07/12122.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Linux] User-Mode Linux 相关资料收集</title><link>http://www.cppblog.com/cpunion/archive/2006/09/03/11991.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sun, 03 Sep 2006 01:45:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/03/11991.html</guid><description><![CDATA[Gentoo上安装UML:<br />http://www.gentoo.org/doc/zh_tw/uml.xml<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-03 09:45 <a href="http://www.cppblog.com/cpunion/archive/2006/09/03/11991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.166发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 01 Sep 2006 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</guid><description><![CDATA[这一版本在强大的民意压力之下取消了上一版的“隐式转换表达式为委托”这一特性，取而代之的是一个lazy关键字。<br /><br />取消的理由是这个转换太隐晦了，最好是显式地标示出这种转换，所以引入一个lazy关键字。D语言还在发展中，很多特性都在尝试，这种修改也不是第一次了。<br /><br />首先看看这个lazy。<br /><br />上一版实现了这样一个特性：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() msg){<br />  writefln(msg());<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log的参数被隐式转化为一个委托，这样只有用到这个值的时候才真正求值。<br /><br />由于这种隐式转化很容易形成陷阱，所以这一版改为一个lazy关键字，看起来要简洁一些了：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(lazy </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[]  msg){<br />  writefln(msg);<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log函数中使用msg这个变量就会调用那个隐式的委托，要注意的是每次取msg的值都会执行这个委托，所以我觉得这个陷阱更大了，当然它把陷阱丢给编写代码的人，而不是使用代码的人，所以好坏还无从分辨。<br /><br />下面这点代码可以演示这个小陷阱：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(lazy </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a){<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> bar(){<br />  writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Call bar()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">12</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br />foo(bar());</span></div><br />看起来bar好像会执行一次，实际上这段代码会打印出3行"Call bar()"，原来使用委托还可以看到一个显式的函数调用呢。<br /><br />另一个member templates特性未见到文档，猜想大概是支持成员函数模板吧。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-01 22:34 <a href="http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Linux] Ubuntu安装资料</title><link>http://www.cppblog.com/cpunion/archive/2006/09/01/11929.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 01 Sep 2006 08:33:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/01/11929.html</guid><description><![CDATA[ATI显卡驱动安装：<br />http://my.opera.com/Qoo/blog/show.dml/425812<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-01 16:33 <a href="http://www.cppblog.com/cpunion/archive/2006/09/01/11929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Linux] Xen安装资料收集</title><link>http://www.cppblog.com/cpunion/archive/2006/08/31/11888.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 31 Aug 2006 03:47:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/31/11888.html</guid><description><![CDATA[前面在Gentoo上安装有失败经历，这次在Ubuntu上安装看看，找了篇和我配置相近的文章，而且过程比较简单：<br />http://linuxvirtualization.com/articles/2006/08/03/xen-on-ubuntu-for-windows<br /><br />另一篇：<br />http://www.howtoforge.com/xen_3.0_ubuntu_dapper_drake<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-31 11:47 <a href="http://www.cppblog.com/cpunion/archive/2006/08/31/11888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[RoR] 修复update_attribute(s)更新全部字段的问题</title><link>http://www.cppblog.com/cpunion/archive/2006/08/26/11712.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 25 Aug 2006 18:10:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/26/11712.html</guid><description><![CDATA[<span class="postbody">这是前段时间有人讨论过的问题： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />order = Order.find(1) <br />order.update_attribute(:status, 'finished') <br /></td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />假定orders表有10个字段，你只想更新其中一个，但active record会生成一个更新全部字段的SQL语句，假定其中一个字段值长度是20K，这个负担可能会有些重。 <br /><br />我尝试解决这个问题，写了个简单的插件： <br /></span>
		<table cellspacing="1" cellpadding="3" width="90%" align="center" border="0">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>代码:</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<br />module ActiveRecord <br />  class Base <br />    def update_attribute(name, value) <br />      update_attributes(name =&gt; value) <br />    end <br /><br />    def update_attributes(new_attributes) <br />      return if new_attributes.nil? <br />      attributes = new_attributes.dup <br />      attributes.stringify_keys! <br />      self.attributes = attributes <br />      update(attributes) <br />    end <br /><br />    private <br />      def update(attrs = nil) <br />        connection.update( <br />          "UPDATE #{self.class.table_name} " + <br />          "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, attrs))} " + <br />          "WHERE #{self.class.primary_key} = #{quote(id)}", <br />          "#{self.class.name} Update" <br />        ) <br />        <br />        return true <br />      end <br /><br />      def attributes_with_quotes(include_primary_key = true, attrs = nil) <br />        (attrs || attributes).inject({}) do |quoted, (name, value)| <br />          if column = column_for_attribute(name) <br />            quoted[name] = quote(value, column) unless !include_primary_key &amp;&amp; column.primary <br />          end <br />          quoted <br />        end <br />      end <br />  end <br />end <br /></td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<p>
						<br />attributes_with_quotes函数的参数搞这么复杂，原因是我想即便是用这段代码替换库里面的部分，也不影响原有代码的正常功能。 <br /><br />可以简单测试一下上面的例子，它生成的SQL语句会简洁很多，大概是这样子： <br />UPDATE orders SET "status" = 'finished' WHERE id = 1<br /><br /><strong>已发现的BUG和修复：<br /></strong><br /><strong>1、没有调用validation (by cookoo)。</strong>由于原有代码调用save，而save被覆盖成有验证的代码，所以具有验证功能。解决办法是增加一段代码：</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<span style="COLOR: #000000">module ActiveRecord<br />  module ValidationsFix<br />    </span>
						<span style="COLOR: #0000ff">def</span>
						<span style="COLOR: #000000"> self.append_features(base) </span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> :nodoc:</span>
						<span style="COLOR: #008000">
								<br />
						</span>
						<span style="COLOR: #000000">      super<br />      base.class_eval do<br />        alias_method :update_attributes_without_validation, :update_attributes<br />        alias_method :update_attributes, :update_attributes_with_validation<br />      end<br />    end<br /><br />    </span>
						<span style="COLOR: #0000ff">def</span>
						<span style="COLOR: #000000"> update_attributes_with_validation(new_attributes)<br />      </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000"> new_attributes.nil?<br />      attributes = new_attributes.dup<br />      attributes.stringify_keys!<br />      self.attributes </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> attributes<br /><br />      </span>
						<span style="COLOR: #0000ff">if</span>
						<span style="COLOR: #000000"> valid?<br />        update_attributes_without_validation(attributes)<br />      </span>
						<span style="COLOR: #0000ff">else</span>
						<span style="COLOR: #000000">
								<br />        </span>
						<span style="COLOR: #0000ff">return</span>
						<span style="COLOR: #000000"> false<br />      end<br />    end<br />  end<br />end<br /><br />ActiveRecord::Base.class_eval do<br />  include ActiveRecord::ValidationsFix<br />end</span>
				</div>
				<p>简单测试通过。</p>
		</span><img src ="http://www.cppblog.com/cpunion/aggbug/11712.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-26 02:10 <a href="http://www.cppblog.com/cpunion/archive/2006/08/26/11712.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.165发布</title><link>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 21 Aug 2006 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</guid><description><![CDATA[前几个版本主要是修正BUG，并没有多少新特性，这个版本终于增加了一个“隐式转换表达式到委托”，这个特性也使“懒惰(或延迟)求值”成为可能。<br /><br />详细信息可见：<a href="http://www.digitalmars.com/d/lazy-evaluation.html">http://www.digitalmars.com/d/lazy-evaluation.html</a><br /><br />它首先解决了一个存在于java中的日志问题，java里面一个写日志标准格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (log.isLoggable(Level.INFO)) {<br />  log.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aaaa</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}</span></div><br />因为log.info的参数求值可能影响性能，所以使用这种繁琐的方式来降低关闭日志时的性能开销。<br /><br />C/C++使用宏来解决这个问题，唯一的问题是修改日志级别会导致项目必须重编译。<br /><br />[注：指的是用宏来定义日志级别的方式，使用其它动态修改日志级别的方式对性能要求很高的项目来说可能不可接受]<br /><br />D语言使用另一种方式来解决，首先要用到“表达式到委托的隐式转换”，下面是委托作为参数时的使用方法：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo( </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] (){<br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br />  }<br />);</span></div><br />因为这个委托并不需要参数，而返回值可以推导，所以在早先的一个版本里，D允许我们简化这个过程：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo({</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;});</span></div><br />DMD 0.165允许我们更进一步：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个字符串参数会被隐式转换成一个委托。<br /><br />现在可以用一样的方法处理日志，在没有宏的系统中，日志函数一般格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] message)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, message);<br />}</span></div><br />为了让它使用懒惰求值这个特性，这里把这个函数的参数改为委托：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, dg());<br />}</span></div><br />从上面提到的内容我们知道使用它也很简单：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">log(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">My name is </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Li Jie</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个参数的求值就是在log函数里面完成的。<br /><br />当然委托会增加一些开销，在上面这个例子中，这个开销是在日志打开时执行委托所带来的，它增加了一次委托调用的开销，不过好在打开日志功能时，其它方面的开销远大过委托调用。关闭日志时，它不会带来开销，它只是把字符串指针压栈改为委托指针压栈。<img src ="http://www.cppblog.com/cpunion/aggbug/11517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-21 13:24 <a href="http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] 用D语言编写Ruby扩展</title><link>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 18 Aug 2006 22:17:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</guid><description><![CDATA[<p>Ruby语言的官方解释程序是使用C语言开发的，一般用C语言来编写扩展。D语言和C语言是二进制兼容的，所以可以使用D语言编写Ruby扩展。<br /></p>
		<p>
				<strong>
						<br />一、移植C库到D的一般过程</strong>
		</p>
		<p>C使用头文件来处理符号依赖，在D里面链接外部库文件时，要使用extern (C)声明来引入符号，这是一个转换过程。</p>
		<p>如何转换一个C头文件到D文件？D文档的htomodule.html有详尽说明。一般的转换过程如下：
</p>
		<p>1、运行预处理程序处理掉头文件里面的宏。</p>
		<p>2、删除经过预处理以后的多余信息。由于C的头文件包含，每个头文件经过预处理以后都会包含一些重复内容，我们需要剔除这部分内容，通过查找行号即可完成。</p>
		<p>3、转换相应声明到D声明，这一步可以使用一个c2h程序来完成。</p>
		<p>注意预处理程序处理完毕以后，宏函数以及宏定义的常量会被去除，这可能不是你想要的，所以最好的办法可能是手工转换。</p>
		<p>另一种调用是在D里面调用动态链接库，这需要你使用implib工具从动态链接库产生一个.lib导入库文件，然后生成D声明，再编译链接即可。如果是在linux下使用共享库，则只需要编写D声明文件，然后直接链接即可。<br /></p>
		<p>
				<strong>
						<br />二、调用C库</strong>
		</p>
		<p>转换完毕以后，就可以调用了。如果你只是要测试一下，就可以只声明使用过的外部函数、变量即可。</p>
		<p>例如我们要编写Programming Ruby里面的一个Ruby Extension例子，相应的D代码如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module test;<br /><br />import ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_init(VALUE self)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_ary_new();<br />  rb_iv_set(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, arr);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> self;<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_add(VALUE self, VALUE anObject)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_iv_get(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />  rb_ary_push(arr, anObject);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> arr;<br />}<br /><br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br /><br />VALUE cTest;<br /><br />alias VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">func_type)();<br /><br />export </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> Init_Test()<br />{<br />  cTest </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_define_class(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, rb_cObject);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">initialize</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_init, </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">add</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_add, </span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">);<br />}<br /><br />}  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> extern(C)</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">
						<br />
				</span>
		</div>
		<p>
				<br />和C代码很相似。由于我们只使用了几个外部函数、变量，所以只需要声明这几个符号即可：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> ruby.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (C){<br />    alias </span>
				<span style="COLOR: #0000ff">ulong</span>
				<span style="COLOR: #000000"> VALUE;<br />    VALUE rb_cObject;<br />    VALUE rb_ary_new ();<br />    VALUE rb_ary_push (VALUE, VALUE);<br />    VALUE rb_iv_set (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">, VALUE);<br />    VALUE rb_iv_get (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">);<br />    VALUE rb_define_class ( </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE);<br />    </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> rb_define_method (VALUE, </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">)(),</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">);<br />}<br /></span>
		</div>
		<p>
				<strong>
						<br />三、生成动态链接库(Windows DLL)或共享库(Linux so文件)</strong>
		</p>
		<p>D语言在Windows上编写DLL，除了要有D源文件以外，还要有DLL定义文件：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.def</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">LIBRARY         Test<br />DESCRIPTION     </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test written in D</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />
						<br />EXETYPE  NT<br />CODE            PRELOAD DISCARDABLE<br />DATA            PRELOAD SINGLE<br /></span>
		</div>
		<p>这是一个通用的格式，只是一些描述信息，因为D中可以使用export关键字导出符号，所以不需要在这里声明导出函数，只有在编写COM DLL时才会增加其它一些信息。</p>
		<p>另外由于D语言要初始化GC以及其它一些信息，所以还需要在DllMain里面调用初始化及终止代码。由于不同平台的初始化过程不完全相同，这里我简单封闭了一下不同平台的初始化代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/library.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.library;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_init();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_term();<br />  version(Windows) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _minit();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleCtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleDtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleUnitTests();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_monitor_staticctor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_critical_init();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_monitor_staticdtor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_critical_term();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start init D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  version(linux) _STI_monitor_staticctor();<br />  version(linux) _STI_critical_init();<br />  gc_init();<br />  version(Windows) _minit();<br />  _moduleCtor();<br />  _moduleUnitTests();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("init finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start term D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  _moduleDtor();<br />  gc_term();<br />  version(linux) _STD_critical_term();<br />  version(linux) _STD_monitor_staticdtor();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("term finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /></span>
		</div>
		<p>现在可以为Windows编写初始化及终止代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/dll.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.dll;<br /><br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import os.library;<br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import std.c.windows.windows;<br /><br />HINSTANCE g_hInst;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (Windows)<br />BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)<br />{<br />  </span>
				<span style="COLOR: #0000ff">switch</span>
				<span style="COLOR: #000000"> (ulReason)<br />  {<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_ATTACH:<br />      d_init();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_DETACH:<br />      d_fini();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_ATTACH:<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_DETACH:<br />      </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> Multiple threads not supported yet</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">      </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">false</span>
				<span style="COLOR: #000000">;<br />  }<br />  g_hInst</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">hInstance;<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">true</span>
				<span style="COLOR: #000000">;<br />}<br /></span>
		</div>
		<p>由于Linux共享库并没有标准的入口函数(或是我不知道它)，这里使用gcc扩展的初始、终止代码，不过是以C语言实现的：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/so.c</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">ruby.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((constructor));<br /></span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((destructor));<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_init();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_fini();<br />}<br /></span>
		</div>
		<p>现在可以尝试编译链接，在Linux上编译命令如下：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">gcc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">c os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.c </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">I </span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">usr</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">lib</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">ruby</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">1.8</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">i686</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">linux <br />gdc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o Test.so test.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o ruby.d </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">shared </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">fPIC </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">lruby</span>
		</div>
		<p>你可以在irb下测试：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">require </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />test </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> Test.</span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000">
						<br />test.add(</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">a</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /></span>
		</div>
		<p>可以看到add总是返回一个array，与期望结果一致。</p>
		<p>使用gdc是因为dmd在linux上无法生成共享库。</p>
		<p>在Windows上的编译命令如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">dmd </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">oftest.dll test.d test.def ruby18.lib os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">dll.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">library.d</span>
		</div>
		<p>ruby18.lib是使用implib从msvcrt-ruby18.dll导出的，这个编译过程很顺利，不过不幸的是它运行有一些问题，大概是一些初始值错误，我暂时还没有找到原因。或许也应该尝试一下gdc，不过我不知道如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件。<br /></p>
		<p>
				<strong>四、项目打算</strong>
		</p>
		<p>打算建立一个rubyd项目，除了转换ruby头文件以外，还要作一些扩展，比如转换D类到ruby类，这方面已有借鉴，比如dsource.org上的pyd项目。</p>
		<p>由于以前在建立项目方面有过失败经历(asgard项目由于兴趣转移和其它原因比如语法丑陋等而未能进行)，这次还是保守一些，先完成D声明的转换，我已经使用工具转换了所有头文件，不过正如前面所说，宏函数和宏常量都丢失了，所以需要重新手工转换。<br /></p>
		<p>
				<strong>五、其它问题</strong>
		</p>
		<p>1、如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件？<strong>如果你知道可以告诉我</strong>，先谢过了。</p>
		<p>2、dmd生成可执行文件问题不大，生成动态链接库或共享库有很大缺陷，特别是不能生成共享库，我可不想再找一个只能再Windows上正常运行的编译器。如何让它改进这些方面？</p>
		<p>3、gdc使用dmd前端和gcc后端，应该会成熟一些，不过一般会比dmd前端版本稍低，而且gdc发布版本不是很频繁，大概4-5个dmd版本才会有一个gdc版本(初略计算)，所以一些新特性不能够及时加入进来。</p><img src ="http://www.cppblog.com/cpunion/aggbug/11427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-19 06:17 <a href="http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gentoo 安装配置资料收集</title><link>http://www.cppblog.com/cpunion/archive/2006/07/17/10158.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 17 Jul 2006 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/07/17/10158.html</guid><description><![CDATA[<b>ipw3945无线网卡安装：</b>
		<br />http://www.flobadon.org/guide/intel-3945.php<br />http://gentoo-wiki.com/HARDWARE_ipw3945<br />http://www.gnome.org/~calum/usability/specs/wireless/<br /><br /><b>Lee venture的安装经验：</b><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.首先emerge一个工具包 emerge wireless</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">tools 安装了之后就有了iwconfig工具<br /></span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">.然后安装驱动程序，内核里面有关ieee80211的选项都取消掉，emerge ipw3945 ，安装的时候会提示要删除内核配置里面的一些东西<br /> </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">usr</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">portage</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">net</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">wireless</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">ieee80211</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">files</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">remove</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">old </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">usr</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">src</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">linux 如果没有x属性就 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">x。<br /></span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">. ln </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">s net.eth0 net.eth1 创建一个新的网络接口<br /></span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">. vi </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">etc</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">conf.d</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">net 配置中增加：<br />  config_eth1</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">dhcp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> )<br />  dhcp_eth1</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">.重启之后就 modprobe ipw3945 就可以用了 执行iwconfig 就可以看见新的eth1了<br /></span><span style="color: rgb(0, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">.现在已经可以用了，就是不知道为什么要modprobe ipw3945才行，而自动ipw3945却不正确</span></div><br /><b>lingcn的安装经验：</b><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">我的机器是IBM T43，在安装无线的时候我的做法是：<br />在内核中直接设定无线网卡，可能是由于intel的授权问题，fireware并没有安装，所以我直接从网上下载了一个，然后依照<br /></span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">etc</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">hotplug</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">firmware.agent中指定的路径把解压后的文件拷贝过去，重启！<br />Everything </span><span style="color: rgb(0, 0, 255);">is</span><span style="color: rgb(0, 0, 0);"> OK</span><span style="color: rgb(0, 0, 0);">!</span></div><br /><br /><b>从stage1安装：</b><br />http://my.opera.com/yonsan/blog/show.dml/80281<br /><br /><b>开启电池电量监视：</b><br />modprobe ac<br />modprobe battery<br />gnome面板里添加<br /><br /><b>添加设备自动挂载、卸载功能。</b><br />http://gentoo-wiki.com/HOWTO_gnome-volume-manager<br />和windows差不多，插入光盘就能在桌面上显示图标，退出光盘自动卸载，不会再出现未umount时按不出来了。<br /><b><br />KDE中美化GTK程序字体：</b><br />http://www.linuxfans.org/nuke/modules.php?name=Forums&amp;file=viewtopic&amp;t=31475<br />/etc/gtk/gtkrc里面添加：<br /><span class="postbody">
style "gtk-default-zh-cn" {
<br />
	font_name = "Helvetica,Simsun,Sans 12"
<br /><br />
}
<br />
class "GtkWidget" style "gtk-default-zh-cn"
</span><br /><img src ="http://www.cppblog.com/cpunion/aggbug/10158.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-07-17 14:07 <a href="http://www.cppblog.com/cpunion/archive/2006/07/17/10158.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>