<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8793914344847646557</id><updated>2011-11-28T08:52:59.873+08:00</updated><category term='ruby'/><category term='mood'/><category term='javascript'/><category term='translate'/><category term='funny'/><category term='smart'/><category term='goodiesh'/><category term='web'/><category term='bug'/><category term='bug fix'/><category term='glassfish'/><category term='fedora'/><category term='google trends'/><category term='diary'/><category term='路人甲'/><category term='c#'/><category term='firefox'/><category term='managment'/><category term='analysis'/><category term='WinForm'/><category term='bookmarklet'/><category term='video'/><category term='.net'/><category term='eclipse'/><category term='site news'/><category term='tweak'/><category term='thought'/><category term='greasemonkey'/><category term='prism'/><category term='thinking'/><category term='tab'/><category term='linux'/><category term='reading'/><category term='ubunto'/><category term='jsf'/><category term='java'/><category term='lifehack'/><category term='translation'/><category term='programming'/><category term='AutoHotKey'/><category term='jsp'/><category term='screensaver'/><category term='goodies'/><category term='game'/><category term='foxsaver'/><category term='tip'/><category term='netbeans'/><category term='JavaFX'/><category term='creative'/><category term='essay'/><category term='annotation'/><category term='firefox 3'/><category term='sql'/><category term='miro'/><category term='bookmark'/><category term='html'/><category term='dictionary'/><category term='history'/><category term='search'/><category term='index'/><category term='asp.net'/><category term='statistics'/><category term='TIOBE'/><category term='pmog'/><category term='mindhack'/><category term='google'/><title type='text'>愛德華日誌</title><subtitle type='html'>增上螺旋．生命之書</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://isong.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-7654024151386340128</id><published>2011-10-14T21:01:00.000+08:00</published><updated>2011-10-14T21:04:45.545+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bookmarklet'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google+ Bookmarklet</title><content type='html'>&lt;br /&gt;
&lt;br /&gt;
&lt;a href="javascript:void(location.href=%27https://plusone.google.com/_/+1/confirm?hl=en&amp;amp;url=%27+encodeURIComponent(location.href))"&gt;Google+&lt;/a&gt;&amp;nbsp; &amp;lt;== 這是 Bookmarklet 連結&lt;br /&gt;
使用方式：&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&amp;nbsp;將上面這個 Bookmarklet 連結，拉到瀏覽器的網址列，或加入書籤。&lt;/li&gt;
&lt;li&gt;在 網址列 或 書籤 中點選剛加入的 Google+ Bookmarklet，就能將目前瀏覽的網頁，分享到 Google+ 上，以下是分享頁面抓圖。&lt;/li&gt;
&lt;li&gt;&amp;nbsp;按下 Share 鈕即可分享。&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-kXJb15Kc93Q/TpgxbxCuBlI/AAAAAAAAEsk/bOJbUl2eepQ/s1600/Screenshot_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="229" src="http://2.bp.blogspot.com/-kXJb15Kc93Q/TpgxbxCuBlI/AAAAAAAAEsk/bOJbUl2eepQ/s320/Screenshot_1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span id="goog_1905449364"&gt;&lt;/span&gt;&lt;span id="goog_1905449365"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-7654024151386340128?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/7654024151386340128/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=7654024151386340128' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/7654024151386340128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/7654024151386340128'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2011/10/google-bookmarklet.html' title='Google+ Bookmarklet'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-kXJb15Kc93Q/TpgxbxCuBlI/AAAAAAAAEsk/bOJbUl2eepQ/s72-c/Screenshot_1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2187730171965053506</id><published>2011-09-06T21:11:00.001+08:00</published><updated>2011-09-06T21:26:39.654+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='annotation'/><title type='text'>用 Java Annotation 簡化命令列參數處理</title><content type='html'>撰寫 Java 命令列程式，免不了要處理命令列參數。常見的作法是就是跑個 for loop, 裡面用 if ... else 去判斷要執行的選項。這樣的作法當然可以達到目的，只是就喪失了程式的美感。&lt;br /&gt;
&lt;br /&gt;
其實在 Web 上，同樣的問題也存在，就是怎麼把 URL 對應到特定的 servlet, action 或 controller 的方法上。這不管是在 Spring Framework 3 Web MVC, Servlet 3 或是 Jessey 中，都有一套近似的解法，就是使用 @Annotation。&lt;br /&gt;
&lt;br /&gt;
OK, 那我們何不如法泡製，也用 @Annotation 來處理命令列參數呢? 我設計的命令列規範如下：&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;將命令列參數區分成「選項」及「選項參數」。選項如 &lt;span style="color: red;"&gt;-start&lt;/span&gt;, &lt;span style="color: red;"&gt;-stop&lt;/span&gt;；選項參數如 -start &lt;span style="color: red;"&gt;localhost 18080&lt;/span&gt; 中，未加 dash 符號的字串，即紅字部分。&lt;/li&gt;
&lt;li&gt;一個命令列可以接受多個選項及多個選項參數。&lt;/li&gt;
&lt;li&gt;支援將選項綁定到主程式裡面的方法，以下我稱之為「選項常式」。&lt;/li&gt;
&lt;li&gt;支援將選項參數綁定到選項常式的參數上。&lt;/li&gt;
&lt;li&gt;支援自動列出所有選項及其說明。&lt;/li&gt;
&lt;li&gt;自動檢查選項參數是否正確。&amp;nbsp;&lt;/li&gt;
&lt;li&gt;支選整數型態的選項參數。&lt;/li&gt;
&lt;/ul&gt;
基於這個規範，我設計出的這組 Command line API，可以透過類似以下方式使用：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;package com.isong.cmdexe;

/**
&amp;nbsp;* Usage example:&amp;lt;pre&amp;gt;
&amp;nbsp;* java -jar ds.jar -start localhost 2011
&amp;nbsp;* java -jar ds.jar -start localhost 2011 -sm
&amp;nbsp;* java -jar ds.jar -stop
&amp;nbsp;* &amp;lt;/pre&amp;gt;
&amp;nbsp;* @author edwardsayer
&amp;nbsp;*/
public class DummyServer {
&amp;nbsp;&amp;nbsp;&amp;nbsp; /**
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* @param args
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] argv) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new CmdExecutor(new DummyServer()).exec(argv);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @CommandArg(value = "-start ip port", desc = "start the server instance.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void doStart(String port, int ip){
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println("Starting server at " + port + ":" + ip + "...");
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @CommandArg(value = "-sm", desc = "start session monitor.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void startSessionMonitor(){
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println("Starting session service...");
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @CommandArg(value = "-stop", desc = "stop the server instance.")
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void doStop(){
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println("Stoping...");
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}
&lt;/pre&gt;
&lt;br /&gt;
從以上的程式碼片段，可以知道這組 Command line API 提供了一個 CmdExecutor 類別, 以及一個 @CommandArg annotation。&lt;br /&gt;
&lt;br /&gt;
 @CommandArg 會在主程式的選項常式上，加上標注訊息，包括選項名稱，以及選項描述。&lt;br /&gt;
&lt;br /&gt;
而CmdExecutor 類別則依據 @CommandArg 所提供的資訊，綁定使用者輸入的參數。另外，若使用者未輸入任何參數，CmdExecutor 則顯示參數提示訊息，這些訊息，其實是我們透過 @CommandArg 加諸在每個選項常式上的訊息。範例如下：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;Available options:
-start ip port
&amp;nbsp;&amp;nbsp;&amp;nbsp; start the server instance.
-sm
&amp;nbsp;&amp;nbsp;&amp;nbsp; start session monitor.
-stop
&amp;nbsp;&amp;nbsp;&amp;nbsp; stop the server instance.
&lt;/pre&gt;
&lt;br /&gt;
接下來，就來了解 CmdExecutor 及 @CommandArg 的實作方式。先看看 @CommandArg 的程式碼：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;@Retention(RetentionPolicy.RUNTIME)
public @interface CommandArg {
    String value();
    String desc() default "";
}
&lt;/pre&gt;
&lt;br /&gt;
可以看到 @CommandArg 包含兩個屬性。value 用來設定選項名稱，而 desc 用來設定選項描述。&lt;br /&gt;
&lt;br /&gt;
CmdExecutor 較為冗長，程式碼如下：&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;public class CmdExecutor {
    private Map&lt;string, method=""&gt; cmdMap;
    private StringBuffer cmdDocs;
    private Object target;
    
    public CmdExecutor(Object target){
        this.target = target;
    }
    
    public int exec(String[] args){
        System.out.println("args = " + Arrays.asList(args));
        initCommands();
        if (args.length == 0) {
            showCommands();
            return 0;
        }
        
        for (int i = 0; i &amp;lt; args.length; i++) {
            if (args[i].startsWith("-")) {
                String option = args[i];
                Method method = cmdMap.get(option);
                if (method == null) {
                    System.out.println("Unknown options: " + option);
                    showCommands();
                    return 1;
                }
                try {
                    Class&lt;!--?--&gt;[] types = method.getParameterTypes();
                    Object[] paras = new Object[types.length];
                    for (int j = 0; j &amp;lt; types.length; j++) {
                        if ( ++i &amp;gt;= args.length || args[i].startsWith("-")) {
                            System.out.println("Invalid option parameter count: " + option);
                            showCommands();
                            return 1;
                        }
                        if(types[j].isAssignableFrom(String.class))
                            paras[j] = args[i];
                        else if(types[j].isAssignableFrom(int.class) 
                                || types[j].isAssignableFrom(Integer.class))
                            paras[j] = Integer.valueOf(args[i]);
                        else
                            throw new IllegalArgumentException("Invalid command parameter type: " + method.getName());
                    }
                    method.invoke(target, paras);
                } catch (Exception e) {
                    e.printStackTrace();
                } 
            }
        }
        return 0;
    }
    
    private void initCommands(){
        if (cmdDocs != null)
            return;
        
        cmdDocs = new StringBuffer("Available options:\n");
        cmdMap = new HashMap&lt;string, method=""&gt;();
        Method[] methods = target.getClass().getMethods();
        for (Method method: methods) {
            CommandArg argCmd = method.getAnnotation(CommandArg.class);
            if (argCmd != null) {
                cmdDocs.append(argCmd.value() + "\n    " + argCmd.desc() + "\n");
                cmdMap.put(argCmd.value().split(" ")[0], method);
            }
        }
    }
    
    private void showCommands(){
        System.out.println(cmdDocs);
    }
}
&lt;/string,&gt;&lt;/string,&gt;&lt;/pre&gt;
&lt;br /&gt;
以上主要程式邏輯放在 exec 這個方法上，它會透過呼叫 initCommands 方法，建立所有選項常式之描述 (cmdDocs) 及對應 (cmdMap)。完成後，就是實際去解析命令列參數。如果沒有任何參數，就透過 showCommands 顯示說明。如果有，就進行選項與主程式方法的對應。&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2187730171965053506?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2187730171965053506/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2187730171965053506' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2187730171965053506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2187730171965053506'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2011/09/java-annotation_06.html' title='用 Java Annotation 簡化命令列參數處理'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-3425020596532394254</id><published>2010-02-28T20:04:00.001+08:00</published><updated>2010-02-28T20:08:27.630+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AutoHotKey'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='goodiesh'/><category scheme='http://www.blogger.com/atom/ns#' term='translation'/><category scheme='http://www.blogger.com/atom/ns#' term='dictionary'/><title type='text'>用 AutoHotkey 啟用雲端字典及翻譯</title><content type='html'>&lt;p&gt;&lt;a href="http://www.google.com.tw/dictionary"&gt;Google 字典&lt;/a&gt;一直是我相當喜愛使用的網路服務，簡潔的版面及清晰的解釋及例句，都是我喜歡它的原因…硬要說它有什麼缺點的話，就是沒有看到日文的支援。固然透過 Firefox 或 Chrome，我們可以很容易的瀏覽器中啟用翻譯服務，但若是想要在其他應用程式中也使用到 Google 字典，就必須借助其他方法了。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.autohotkey.com/"&gt;AutoHotKey&lt;/a&gt; 是一個 Windows 下的桌面工具，可以讓我們透過自訂的快速鍵，啟動特定的應用程式、開啟文件、或指定的 URL 等。我們可以利用 AutoHotKey 的功能，在桌面上一鍵啟動 Google 字典及翻譯。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;下載 &lt;a href="http://www.autohotkey.com/"&gt;AutoHotKey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;執行安裝&lt;/li&gt;
&lt;li&gt;安裝完成後，執行 AutoHotKey&lt;/li&gt;
&lt;li&gt;在 Windows 的 System Tray 中，在 AutoHotKey 的 [H] 按鈕上按右鍵，帶出右鍵功能表，選擇「Edit This Script」&lt;/li&gt;
&lt;li&gt;此時 AutoHotKey 預設會以 Windows 內建的「記事本」(Notepad) 開啟 AutoHotKey.ahk，供我們編輯&lt;/li&gt;
&lt;li&gt;接下來就得編輯 AutoHotKey 的指定碼了，所幸相當簡單。其 Help 中有詳細的說明，我把常用的網頁服務設定如下的代碼區塊。&lt;/li&gt;
&lt;li&gt;網友們可複製以下程式碼，貼到 AutoHotKey.ahk 檔案最後，然後存檔，關閉記事本。&lt;/li&gt;
&lt;li&gt;使用 AutoHotKey 的右鍵功能表，執行「Reload This Script」。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;至此大功告成，以後在任何應用程式中，只要先選定 (反白) 要查詢的文字，然後按下 Win + X 組合鍵，就可將選定文字帶至 Google 字典中查詢；此外，你也可以使用 Win + S 啟用 Google 搜尋，或使用 Win + Z 啟用 Google 翻譯。&lt;/p&gt;
&lt;p&gt;另外，如果你想要讓 Windows 啟動時就自動執行 AutoHotKey.ahk，可以為 AutoHotKey.ahk 建立一個捷徑，並將捷徑放置在開始功能表裡面的「啟動」目錄即可。&lt;/p&gt;
&lt;p&gt;Ahk 代碼：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
;; 定義按 Win + S 鍵，啟用 Google 搜尋
#s::
clipboard = ; Empty the clipboard
Send, ^c
ClipWait, 2
Run http://www.google.com.tw/search?hl=zh-TW&amp;amp;q=%clipboard%
return

;; 定義按 Win + X 鍵，啟用 Google 字典
#x::
clipboard = ; Empty the clipboard
Send, ^c
ClipWait, 2
Run http://www.google.com.tw/dictionary?aq=f&amp;amp;oq=breed&amp;amp;langpair=en|zh-TW&amp;amp;hl=zh-TW&amp;amp;q=%clipboard%
return

;; 定義按 Win + Z 鍵，啟用 Google 翻譯
#z::
clipboard = ; Empty the clipboard
Send, ^c
ClipWait, 2
Run http://translate.google.com.tw/translate_t#auto|zh-TW|%clipboard%
return
&lt;/pre&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/AutoHotKey" class="ztag" rel="tag"&gt;AutoHotKey&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/dictionary" class="ztag" rel="tag"&gt;dictionary&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/goodiesh" class="ztag" rel="tag"&gt;goodiesh&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/google" class="ztag" rel="tag"&gt;google&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/translation" class="ztag" rel="tag"&gt;translation&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-3425020596532394254?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/3425020596532394254/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=3425020596532394254' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3425020596532394254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3425020596532394254'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2010/02/autohotkey.html' title='用 AutoHotkey 啟用雲端字典及翻譯'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-4227049308371130613</id><published>2009-09-15T11:43:00.001+08:00</published><updated>2009-09-15T11:48:13.770+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='WinForm'/><title type='text'>WinForm: 如何判斷表單是否開啟在 Visual Studio 的 Designer 中</title><content type='html'>&lt;p&gt;最近工作上用到比較多微軟的開發工具，像是 Visual Studio, Reporting Servoces, ASP.NET 等。&lt;/p&gt;
&lt;p&gt;我們採用了一套 UI Framework，可以在 ASP.NET 上，以 WinForm 的程式設計模式來開發 Web 表單。在表單開發上，可完全免除自行撰寫 Client 端 JavaScript 的需要。簡言之，這種開發模式具有 WinForm 的優點，相對的，開發 WinForm 時所需要面對的問題，這裡同樣要面對。&lt;/p&gt;
&lt;p&gt;例如，在開發 WinForm 表單時，我們常會在元件的 Load 事件載入資料來源，進行資料綁定。在執行環境這樣的邏輯沒有問題，但在開發環境，以 Visual Studio 的 Designer 開啟元件時，就可能會遇到無法讀取設定檔、資料連結錯誤等等問題，而造成 Designer 無法順利開啟表單。&lt;/p&gt;
&lt;p&gt;我查詢了一下，在 &lt;a href="http://social.msdn.microsoft.com/forums/en-US/winformsdesigner/thread/80c6894a-e3b7-4376-8020-43d4ed97b1ee/"&gt;MSDN Windows Developer Center&lt;/a&gt; 上也有人詢問這個問題，其中有個開發者已經給了一個可用的 solution，但因為他的描述過於複雜，且要求改寫基底類別，所以我擷取了他的解法，加以簡化。&lt;/p&gt;
&lt;p&gt;首先，我們撰寫一個 GuiUtil 類別，其中包括下列方法：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
public static bool InDesignMode() 
{
    try 
    { 
        return System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
    }
    catch
    {
        return false;
    }
}
&lt;/pre&gt;
&lt;p&gt;如此一來，我們就可以採用以下的程式碼，在 Client 端程式的 Load 事件中進行呼叫，而不會產生設計畫面出不來的狀況了。&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
if (!GuiUtil.InDesignMode())
{
        InitDataBinding();
}
&lt;/pre&gt;
&lt;p&gt;-- 完 --&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-4227049308371130613?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/4227049308371130613/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=4227049308371130613' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/4227049308371130613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/4227049308371130613'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/09/winform-visual-studio-designer.html' title='WinForm: 如何判斷表單是否開啟在 Visual Studio 的 Designer 中'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-1005670315246946183</id><published>2009-07-07T09:46:00.001+08:00</published><updated>2009-07-07T09:46:45.995+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>有趣的 MIS 大大</title><content type='html'>&lt;p&gt;剛剛 MIS 大大寄來一封停機公告，重點在那張圖：&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir="ltr"&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;各位辛苦的系統開發大大們，&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;這件事情已經拖了一個多月了，實在不一在拖下去了…&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;知道各位都相當的忙碌，不過一個多月的時間應該也足夠才對。&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;剛剛看過黃曆，7/18 是個好日子，我們會設定在 7/18 子時系統自動關機，之後就不再提供服務了！&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;如果各位還有資料沒有轉到新的測試主機 xx.xxx.xx.xxx 的，請利用這兩週趕快轉移。&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt;感謝您的配合！！&lt;/p&gt;
&lt;p style="MARGIN: 0cm 0cm 0pt"&gt; &lt;/p&gt;
&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3598/3696547160_db0f669e6d.jpg" alt="yellow calendar.png" height="285" width="508"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-1005670315246946183?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/1005670315246946183/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=1005670315246946183' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1005670315246946183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1005670315246946183'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/07/mis.html' title='有趣的 MIS 大大'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3598/3696547160_db0f669e6d_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-8857383361109009991</id><published>2009-07-04T09:39:00.001+08:00</published><updated>2009-07-04T09:48:18.593+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='bookmark'/><category scheme='http://www.blogger.com/atom/ns#' term='tab'/><category scheme='http://www.blogger.com/atom/ns#' term='goodies'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Firefox 小技巧--將收藏庫開啟於分頁標籤中</title><content type='html'>&lt;p&gt;Open Firefox Library in a Tab&lt;/p&gt;
&lt;p&gt;不曉得有沒有人曾想過，把 Firefox 內的收藏庫 (Library, 管理書籤跟歷史的使用界面)，開啟於分頁標籤中，而不是獨立視窗中。&lt;/p&gt;
&lt;p&gt;如果你也曾想這麼做，那就這麼做吧 -- 在網址列中輸入以下 URL：&lt;/p&gt;
&lt;p&gt;chrome://browser/content/places/places.xul&lt;/p&gt;
&lt;p&gt;噹噹…&lt;/p&gt;
&lt;p&gt;現在收藏庫便開啟於分頁標籤之中了：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3686147092/" title="Flickr 上 edwardsayer 的 Firefox Library in a Tab"&gt;&lt;img src="http://farm3.static.flickr.com/2586/3686147092_e530f0f41d.jpg" alt="Firefox Library in a Tab" height="356" border="0" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/bookmark" class="ztag" rel="tag"&gt;bookmark&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/firefox" class="ztag" rel="tag"&gt;firefox&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/goodies" class="ztag" rel="tag"&gt;goodies&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/history" class="ztag" rel="tag"&gt;history&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/tab" class="ztag" rel="tag"&gt;tab&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-8857383361109009991?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/8857383361109009991/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=8857383361109009991' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8857383361109009991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8857383361109009991'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/07/firefox.html' title='Firefox 小技巧--將收藏庫開啟於分頁標籤中'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2586/3686147092_e530f0f41d_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-4387673338832920723</id><published>2009-06-05T09:01:00.001+08:00</published><updated>2009-06-05T09:01:39.372+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TIOBE'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='index'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>JavaFX 與 TIOBE Programming Community Index</title><content type='html'>&lt;p&gt;&lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE Programming Community Index&lt;/a&gt; 是一個用來評量程式語言受歡迎程度的指標，其排名方式，在頁面上說明如下：&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir="ltr"&gt;
&lt;p&gt;&lt;span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: 16px 'times new roman'; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="TEXT-ALIGN: left; LINE-HEIGHT: 18px; FONT-FAMILY: Arial; COLOR: rgb(102,102,102); FONT-SIZE: 12px" class="Apple-style-span"&gt;The index is updated once a month. The ratings are based on the number of skilled engineers world-wide, courses and third party vendors. The popular search engines Google, MSN, Yahoo!, Wikipedia and YouTube are used to calculate the ratings. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我大概每個月初都會略微的瞄一下，了解一下目前各主要程式語言的排名狀況。昨天在檢視的時候，發現了 Sun 推了一陣子的 JavaFX 語言，並沒有在排名裡面。可能原因是 JavaFX 並沒有在百大排名裡面，或者是 TIOBE 並沒注意到這個程式語言。而我發現網頁上有這一行字：&lt;/p&gt;
&lt;blockquote style="MARGIN-RIGHT: 0px" dir="ltr"&gt;
&lt;p&gt;&lt;span style="WIDOWS: 2; TEXT-TRANSFORM: none; TEXT-INDENT: 0px; BORDER-COLLAPSE: separate; FONT: 16px 'times new roman'; WHITE-SPACE: normal; ORPHANS: 2; LETTER-SPACING: normal; COLOR: rgb(0,0,0); WORD-SPACING: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"&gt;&lt;span style="TEXT-ALIGN: left; LINE-HEIGHT: 18px; FONT-FAMILY: Arial; COLOR: rgb(102,102,102); FONT-SIZE: 12px" class="Apple-style-span"&gt;If you have the impression there is a programming language lacking, please notify us at &lt;a style="COLOR: rgb(103,155,195); TEXT-DECORATION: none" href="mailto:tpci@tiobe.com"&gt;tpci@tiobe.com&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是說，如果你發現 TIOBE 可能漏掉某個程式語言的排名，可以寫信告訴他們。因此，我想先確定一下，JavaFX 目前是否有資格擠進百大。我用了一個「比較法」來確認，也就是，如果某語言在 Top 100 或 Top 50，而 JavaFX 的熱門程式與該語言相當，那麼 JavaFX 也該在 Top 100 或 Top 50 左右。&lt;/p&gt;
&lt;p&gt;這個用來做比較的語言，最好不要有一字多義的傾向。例如，Ruby、Python、Groovy、Alice 等就都不適合，因為他們不是一字多義，就是菜市場名字。後來我決定以 Erlang 來做比較，比較結果如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;&lt;a href="http://www.google.com/insights/search/#q=javafx,erlang&amp;amp;cmpt=q"&gt;javafx vs. erlang&lt;/a&gt;: 從 2004 年開始比較。&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href="http://www.google.com/insights/search/#q=javafx,erlang&amp;amp;date=today 12-m&amp;amp;cmpt=q" title="javafx vs. erlang last 12 months"&gt;javafx vs. erlang&lt;/a&gt;: 近 12 個月的趨勢。&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;就查詢量來看，javafx 有超越 erlang 的趨勢。有了這個發現，我便動筆寫了信給 TIOBE 的成員，而沒想到昨天才寄的信，今早就收到回信。而 TIOBE 也把 JavaFX 納入排名，目前排名第 72。另一個值得小小高興一下的是，TIOBE 的回信者 Paul 在信中說道，為了感謝我的建議，他會在最近一期的排名中公提到我的名字。看看 6 月份的排名，哇，真的有提到我耶 ^_^!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-4387673338832920723?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/4387673338832920723/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=4387673338832920723' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/4387673338832920723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/4387673338832920723'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/06/javafx-tiobe-programming-community.html' title='JavaFX 與 TIOBE Programming Community Index'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-8334016958318604431</id><published>2009-05-05T22:15:00.001+08:00</published><updated>2009-05-05T22:15:02.212+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>有趣的 Ruby 字串操作</title><content type='html'>&lt;p&gt;irb(main):025:0&amp;gt; a= "abc def"
&lt;br id="od-8"/&gt;
=&amp;gt; "abc def"
&lt;br id="od-80"/&gt;
irb(main):026:0&amp;gt; a["def"] = "abc"
&lt;br id="od-81"/&gt;
=&amp;gt; "abc"
&lt;br id="od-82"/&gt;
irb(main):027:0&amp;gt; a
&lt;br id="od-83"/&gt;
=&amp;gt; "abc abc"
&lt;br id="od-84"/&gt;
irb(main):028:0&amp;gt; a["abc"] = "xyz"
&lt;br id="od-85"/&gt;
=&amp;gt; "xyz"
&lt;br id="od-86"/&gt;
irb(main):029:0&amp;gt; a
&lt;br id="od-87"/&gt;
=&amp;gt; "xyz abc"
&lt;br id="od-88"/&gt;
irb(main):030:0&amp;gt; a["abc"]
&lt;br id="od-89"/&gt;
=&amp;gt; "abc"
&lt;br id="od-810"/&gt;
irb(main):031:0&amp;gt; a["def"]
&lt;br id="od-811"/&gt;
=&amp;gt; nil
&lt;br id="od-812"/&gt;
irb(main):032:0&amp;gt;
&lt;br id="od-813"/&gt;
&lt;br id="od-814"/&gt;
&lt;span style="FONT-FAMILY: Verdana" id="od-815"&gt;&lt;span style="FONT-SIZE: 0.75em"&gt;date &lt;strong&gt;=&lt;/strong&gt; "2009/12/12"
&lt;br/&gt;
month, day, year = date.split('/')
&lt;br id="od-817"/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/programming" class="ztag" rel="tag"&gt;programming&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/ruby" class="ztag" rel="tag"&gt;ruby&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-8334016958318604431?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/8334016958318604431/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=8334016958318604431' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8334016958318604431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8334016958318604431'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/05/ruby.html' title='有趣的 Ruby 字串操作'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-508927344653512984</id><published>2009-04-23T09:28:00.002+08:00</published><updated>2009-05-12T22:10:00.916+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>C # 裡面 ?? (雙問號)運算子的妙用</title><content type='html'>&lt;p&gt;?? 運算子是在 2.0 版後新增的，至今我在別人的程式中還很少看到有在使用。
&lt;br/&gt;
它的使用方式如下：&lt;/p&gt;
&lt;p&gt;a = b ?? c;&lt;/p&gt;
&lt;p&gt;上式的意思是，如果 b != null，那就把 b 的值指定給 a，否則就把 c 的值指定給 a。
&lt;br/&gt;
照理講，?? 的功能完全可以由 ?: 運算子替代，如上式可以改寫如下：&lt;/p&gt;
&lt;p&gt;a = b != null ? b : c;&lt;/p&gt;
&lt;p&gt;不過，?? 對於簡化程式碼很有幫助，我相信許多 one liner 會很喜歡它，例如：&lt;/p&gt;
&lt;p&gt;if (Session["WEB_TYPE"] == null)
&lt;br/&gt;
{
&lt;br/&gt;
Session.Add("WEB_TYPE", "");
&lt;br/&gt;
}&lt;/p&gt;
&lt;p&gt;可以改寫為：&lt;/p&gt;
&lt;p&gt;Session["WEB_TYPE"] = Session["WEB_TYPE"] as string ?? "";&lt;/p&gt;
&lt;p&gt;?? 的另一個特點是使用上可以串連，例如：&lt;/p&gt;
&lt;p&gt;string a = null;
&lt;br/&gt;
string b = null;
&lt;br/&gt;
string c = "c";
&lt;br/&gt;
string d = a ?? b ?? c;&lt;/p&gt;
&lt;p&gt;這樣的意思，也就是由左到右，找到第一個非 null 值的變數，指定給 d。&lt;/p&gt;
&lt;p&gt;於是，如果有一段程式如下 (抓取系統中的舊程式碼舉個例子)：&lt;/p&gt;
&lt;p&gt;if (Session["WEB_TYPE"] == null)
&lt;br/&gt;
{
&lt;br/&gt;
Session.Add("WEB_TYPE", "");
&lt;br/&gt;
}&lt;/p&gt;
&lt;p&gt;//接收 Web_type
&lt;br/&gt;
if (!IsPostBack)
&lt;br/&gt;
{
&lt;br/&gt;
if (Request.QueryString["WEB_TYPE"] != null)
&lt;br/&gt;
{
&lt;br/&gt;
webtype = Request.QueryString["WEB_TYPE"].ToString();
&lt;br/&gt;
Session["WEB_TYPE"] = webtype;
&lt;br/&gt;
}
&lt;br/&gt;
}&lt;/p&gt;
&lt;p&gt;可以用 ?? 運算子改寫成以下版本：&lt;/p&gt;
&lt;p&gt;Session["WEB_TYPE"] = Session["WEB_TYPE"] as string ?? Request.QueryString["WEB_TYPE"] ?? "";&lt;/p&gt;
&lt;p&gt;這樣程式就精簡許多，也更好理解與維護了。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-508927344653512984?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/508927344653512984/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=508927344653512984' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/508927344653512984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/508927344653512984'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/04/c.html' title='C # 裡面 ?? (雙問號)運算子的妙用'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2853690290866278370</id><published>2009-04-22T10:17:00.001+08:00</published><updated>2009-04-22T10:18:34.645+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='essay'/><category scheme='http://www.blogger.com/atom/ns#' term='路人甲'/><title type='text'>在麥當勞看了一場戲</title><content type='html'>&lt;p&gt;一個皮膚黝黑的男子，兩眼無神的呆坐在餐飲區的一角。
&lt;br/&gt;
一個體格壯碩的男子帶著一個清瘦的女生走了進來，坐在黝
&lt;br/&gt;
黑男子的身旁，對他交待了幾句，拍拍了那女生的肩，便走
&lt;br/&gt;
開了。&lt;/p&gt;
&lt;p&gt;那男的哭喪著臉，哀求的詢問著那女生，那女生正顏厲色的
&lt;br/&gt;
反過來詰問那個男的… 那男的無言以對，熱淚涔涔而下，
&lt;br/&gt;
這種狀況來回幾次，那男的奪門而出。&lt;/p&gt;
&lt;p&gt;那個壯碩的男子回來，再度拍拍那女生的肩，安慰她幾句，
&lt;br/&gt;
再度離去把那女生留在現場。&lt;/p&gt;
&lt;p&gt;最後，另一個面容白晰的男生走了進來，拉著那女生的手，
&lt;br/&gt;
摟了摟那女生的肩，聊了幾句。那女生嘆了口氣，如釋重負
&lt;br/&gt;
般的站了起來，那男生也跟著站了起來，兩個人牽著手，漫
&lt;br/&gt;
步離開現場。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2853690290866278370?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2853690290866278370/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2853690290866278370' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2853690290866278370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2853690290866278370'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/04/blog-post.html' title='在麥當勞看了一場戲'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2846175292917777708</id><published>2009-03-15T01:03:00.005+08:00</published><updated>2011-10-26T00:37:37.398+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='fedora'/><category scheme='http://www.blogger.com/atom/ns#' term='ubunto'/><title type='text'>老筆電擺脫 Windows 大復活 (Resolve sound issue in Ubuntu 11.10)</title><content type='html'>[20111026 更新]&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;解決 Ubuntu 11.10 沒有聲音的問題&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;How to resolve sound issue in Ubuntu 11.10 &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
話說我在升級了 11 10 版之後，沒有聲音的狀況又出現了。而這個版本很奇怪的地方，在於無法直接用圖形介面解決這個問題，就像這個&lt;a href="https://answers.launchpad.net/ubuntu/+source/alsa-driver/+question/173676"&gt;連結&lt;/a&gt;裡面所說的狀況一樣:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
I said like in ubuntu 11.04 my sound worked perfectly just after  changing the sound setting ,,in the hardware i changed it to analog  stereo duplex and in the output i changed it to analog no amplifier..but  in 11.10..i tried to do the same setting but the output setting of  analog no amplifier reverts back to amplifier,&lt;br /&gt;
&lt;wbr&gt;&lt;/wbr&gt;,automatically.&lt;wbr&gt;&lt;/wbr&gt;.and no sound output plays...&lt;/blockquote&gt;
&lt;br /&gt;
選了不用 External Amplifier，系統還是會自動跳回去，後來我是在命令列底下，執行以下的指令，就解決這個問題了。&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;amixer sset&amp;nbsp; 'External Amplifier',0 off&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
[Original Post]&lt;br /&gt;
4、5 年前買了一台華宇的 Fox F35 11 吋 "小" 筆電，至今跑起來仍是嚇嚇叫，就一款跑了 4、5 年的老筆電而言，現在還能使用它，算是相當值回票價了。不過畢竟服役年資已深，系統內已裝了太多奇奇怪怪的程式，在重灌之際，我便想為 F35 換上 Linux，讓它從 Windows 世界中解放出來，而我也可以多了一台可以跑 Linux 的玩具。 &lt;br /&gt;
我為 F35 裝上 Fedora 最新版，大抵上安裝程序相當簡便，約不操過 20 分鐘，即可安裝完成。稍經調校設定後，即可使用無線上網，一切看似美好。然而就在我想試著播放 MP3 之際，卻發現 F35 竟變成了啞巴! 明明有抓到音效卡，可是就是不出聲。在 Google 上以 "Fedora 音效" 等關鍵字找了幾天，沒找到解決方案，想說我還好其他很多事要忙，就先把這事擺一邊。 &lt;br /&gt;
今晚回到家後，心想趁著一點空檔，換派 Ubuntu 上場，看是否能解決這個問題。Ubuntu 安裝好之後，最讓我感動的是，它直接就抓到 WiFi 無線網路連線，一切簡直是 too good to be true。然而我知道不能高興的太早，因為真正的挑戰，還在於讓我這 F35 發出聲來。果然，進入「音效設備設定」畫面，點選測試按鈕，Ubuntu 也是無聲以對，是哪裡出了問題? 這次改以 "Ubuntu 音效" 為關鍵字進行查詢，資料看起來比 Fedora 多了一些，經過各種資料的參照及測試後，終於讓 F35 可以奏出悠揚的樂章… &lt;br /&gt;
其實使 F35 電腦出聲的關鍵，說出來可能會讓人搖頭嘆惜…因為，那根本不是 Linux 的音效支援不足的問題，而是 Linux 的音效設定太強，導致可能在某些機器上，不調整預設設定，你的 Linux 機器就會變成啞巴! 以我的狀況為例，我就是改了 External Amplifier 設定，將它 disable 後，就發出聲音來了。 &lt;br /&gt;
稍微說明一下 disable External Amplifier 的方式。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;以右鍵點選視窗右上角的 "喇叭" 圖示&lt;/li&gt;
&lt;li&gt;在選單中點選 "啟動音效控制程式"&lt;/li&gt;
&lt;li&gt;在開啟的 "音量控制" 視窗中，點選 "偏好設定" 按鈕&lt;/li&gt;
&lt;li&gt;在出現的 "音量控制偏好設定" 清單中，將 "External Amplifier" 前面的 check box 把勾&lt;/li&gt;
&lt;li&gt;然後點選 "關關"，回到 "音量控制" 視窗&lt;/li&gt;
&lt;li&gt;切換到 "開關" 頁籤&lt;/li&gt;
&lt;li&gt;將 "External Amplifier" 後面的 check box 打勾取消&lt;/li&gt;
&lt;/ol&gt;
就這樣。要注意的是，雖然我前面一直在說 F35 的狀況，但就我查到的資料，其他人在別台機器上，也遇到同樣的問題，也是透過把這個選項 disable 掉就得以解決。所以如果你也遇到相同的狀況，也許也可以用這方式試試看。另外，如果你的 Linux 是 Fedora，這個程序也應該適用。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2846175292917777708?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2846175292917777708/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2846175292917777708' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2846175292917777708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2846175292917777708'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/03/windows.html' title='老筆電擺脫 Windows 大復活 (Resolve sound issue in Ubuntu 11.10)'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-9156325816910119468</id><published>2009-03-13T01:31:00.001+08:00</published><updated>2009-03-13T01:31:51.635+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='smart'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='goodies'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>搜尋引擎設定也能帶著走</title><content type='html'>&lt;p&gt;Foxmarks/Xmarks 這類線上書籤同步工具的出現，讓我們在不同的電腦與瀏覽器之間同步書籤。我習慣叫這種應用叫 "書籤帶著走"。但是，不曉得有沒有人和我一樣，想把瀏覽器上的其他設定也帶著走呢？&lt;/p&gt;
&lt;p&gt;對我來講，除了書籤之外，"搜尋引擎設定" 也是我想帶著走的。這裡的搜尋引擎，提的是「搜尋工具列」或是「Smart Search」裡面的搜尋引擎。&lt;/p&gt;
&lt;p&gt;「搜尋工具列」大家比較清楚，就是網址列旁的搜尋框。而 Smart Search 知道的人或愛用的人可能比較少，有人叫它「智能搜尋」，或叫 Quick Searches，這裡有篇&lt;a href="http://forum.slime.com.tw/thread133160.html"&gt;文章&lt;/a&gt;介紹；基本上是讓你把書籤當成搜尋引擎使用的一種方式。&lt;/p&gt;
&lt;p&gt;過去我一直覺得奇怪，Firefox 為何要有兩套不同的搜尋機制，也不了解這兩者間如何選擇。後來因為有了 ConQuery 及 Context Search 這類套件，讓我可以在右鍵選單上直接使用搜尋功能，這種方便性讓我一直以「搜尋工具列」裡的搜尋引擎作為我的主要搜尋工具。&lt;/p&gt;
&lt;p&gt;但是，搜尋工具列裡的搜尋引擎在使用上卻有一個缺點，那就是，他們無法像書籤一樣，可以帶者走… 因此，在 Firefox 2.x 版的年代，我便透過一套叫 FireUploader 的工具，手動將搜尋引擎設定上傳到某個網站，然後再於別台電腦將它們下載回來，但這終究不是長久之計啊!&lt;/p&gt;
&lt;p&gt;後來找到一個就叫做 SmartSearch 的套件，這個套件做的事與 ConQuery 或 Context Search 類似，就是讓你可以在右鍵選單上，選擇你要使用的搜尋引擎進行查詢，但不同的地方在於，它的搜尋引擎選單是來自「智能搜尋」的 Quick Searches Bookmarks，這代表著，你的搜尋引擎清單就是書籤連結，是可以「帶著走」的--只要你同時安裝 SmartSearch 及 Foxmarks/Xmarks 即可。&lt;/p&gt;
&lt;p&gt;相關連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/zh-TW/firefox/addon/188"&gt;SmartSearch&lt;/a&gt;: Firefox 右鍵選單搜尋套件&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/zh-TW/firefox/addon/231"&gt;ConQuery&lt;/a&gt;: Firefox 右鍵選單搜尋&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/zh-TW/firefox/addon/240"&gt;Context Search&lt;/a&gt;: Firefox 右鍵選單搜尋&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/zh-TW/firefox/addon/2410"&gt;Foxmarks&lt;/a&gt;: Foxmarks 書籤同步套件&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmarks.com/"&gt;Xmarks&lt;/a&gt;: Firefox 的後繼者&lt;/li&gt;
&lt;/ul&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/search" class="ztag" rel="tag"&gt;search&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/smart" class="ztag" rel="tag"&gt;smart&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-9156325816910119468?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/9156325816910119468/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=9156325816910119468' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/9156325816910119468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/9156325816910119468'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/03/blog-post.html' title='搜尋引擎設定也能帶著走'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2467823279806298921</id><published>2009-03-04T10:16:00.000+08:00</published><updated>2009-03-04T10:17:04.372+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>SQL 設計小技巧--用 ISNULL 或 NVL 達到選擇性條件的下法</title><content type='html'>&lt;p&gt;透過表單介面查詢資料庫時，常會遇到一種情況，即表單介面上有很多查詢選項，但不一定都要設定。若是不設定，代表 "忽略" 那條查詢選項。&lt;/p&gt;
&lt;p&gt;舉個例子，假設畫面上有個欄位是要依照 "學歷" 及 "性別" 取出會員資料，因此，查詢資料庫的 SQL 可能如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   select * from member where education = @education and gender = @gender
&lt;/pre&gt;
&lt;p&gt;若此時使用者未設定學歷條件，則查詢語法變成：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   select * from member where education = @education
&lt;/pre&gt;
&lt;p&gt;當條件變動，還有另外兩種可能的查詢語法：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   select * from member where gender = @gender
&lt;/pre&gt;
&lt;pre class="prettyprint"&gt;
   select * from member where education
&lt;/pre&gt;
&lt;p&gt;如果你是用 PHP，由前端先組好查詢法語，再傳入後端資料庫處理，這沒有多大問題，只要透過一些 if 的判斷即可。但想像一下，若有 10 個查詢選項，那組合 SQL 語法的過程，不會讓你感到高興吧。&lt;/p&gt;
&lt;p&gt;如果你是透過 ORMapping，雖然可以避免自行組合 SQL 查詢語法，卻也免不了要判斷該參數是否已設定，有設定的參數，才需加入 query criteria 中。&lt;/p&gt;
&lt;p&gt;透過程式語言組裝查詢條件，再送入資料庫查詢，除了設計上的不便外，也不是所有的情況下都可使用。例如，假設你使用微軟的 &lt;strong&gt;Reporting Services&lt;/strong&gt;，報表資料集的來源，直接就對應到 "靜態的" SQL 語法，你無法在執行期才去組裝它，這時就要使用不同的作法。&lt;/p&gt;
&lt;p&gt;一個好用的技巧，是善用 ISNULL (MS SQL/T-SQL) 或 NVL (Oracle/PLSQL) 函式，它們的語法近似：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ISNULL(A, B)&lt;/li&gt;
&lt;li&gt;NVL(A, B)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面兩個式子，都代表著，若是 A 不等於 NULL，則傳回 A，否則傳回 B。&lt;/p&gt;
&lt;p&gt;這個東西的有用之處，讓我們直接透過例子來解釋，把上面的查詢語句改為如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   --MS SQL
   select * from member where education = ISNULL(@education, education) and gender = ISNULL(@gender, gander)

   --Oracle
   select * from member where education = NVL(:education, education) and gender = NVL(:gender, gander)
&lt;/pre&gt;
&lt;p&gt;類似這樣的式子，就可以解決我們&lt;strong&gt;所有的查詢組合&lt;/strong&gt;情況。我們取出其中一段做分解說明：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   gender = ISNULL(@gender, gander)
&lt;/pre&gt;
&lt;p&gt;@gender 代表查詢參數，當 @gender 未設定查詢條件時，我們讓他預設值為 NULL，結果 gender = ISNULL(NULL, gander) 就變成 gender = gender，而這個條件總是成立，所以就等於沒下這個條件。反之，或 gender 設定為 'F' 時，gender = ISNULL('F', gander) 就變成 gender = 'F'，如此一來，就只會查詢出性別為 F 的會員資料。&lt;/p&gt;
&lt;p&gt;基於這一原理，即使你的查詢條件有 20 個、30 個，你也不用再費心思索如何組裝查詢條件了。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2467823279806298921?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2467823279806298921/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2467823279806298921' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2467823279806298921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2467823279806298921'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/03/sql-isnull-nvl.html' title='SQL 設計小技巧--用 ISNULL 或 NVL 達到選擇性條件的下法'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-1612957763702210167</id><published>2009-02-24T12:05:00.001+08:00</published><updated>2009-02-24T13:06:36.485+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jsp'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>如何取得 Web 應用程式的根目錄 Context URL</title><content type='html'>&lt;p&gt;我們常常在開發 Web 應用程式時，會有需要取得 Context URL。例如，為了透過這個 URL 取得某些資源。Context URL，也就是 Web 應用程式根目錄的 URL。例如，給定一個 URL 如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
    http://test.com:8080/AppContext/path/to/your/page
&lt;/pre&gt;
&lt;p&gt;則 Context URL 指的是：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
    http://test.com:8080/AppContext   
&lt;/pre&gt;
&lt;p&gt;如果我們都是以相對路徑 (相對於根目錄或或目前路徑) 的方式來存取資源，那直接使用 Context URL 的必要性就比較低了。不過有時候並無法使用相對路徑，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;因為配合 API 的呼叫，你不曉得這個 API 會在虛擬路徑的第幾層呼叫，因此就無法提供相對路徑。&lt;/li&gt;
&lt;li&gt;因為配合某種 code gen 機制，你要傳入一個 URL。&lt;/li&gt;
&lt;li&gt;因為採用了某種 URL dispatch 的機制，導致你網頁相對路徑發生偏差。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;當然還有其他原因。而面對這個問題的解法，傳統上是在 web.config 或 web.xml 裡面去定義一個類似 HOST_URL 的參數來解決。但缺點是，每次 deploy 時，就得變更 HOST_URL 的設定，除了顯得不便之外，因會增加 API 與環境變數的相依性，實在不能算是很好的做法。因此透過程式自動抓取 ContextURL 的作法，便有其必要。&lt;/p&gt;
&lt;p&gt;現在，我們假設我們的 ContextURL 就是以上的形式，而不是 WebServer 的根目錄 (例如 &lt;a href="http://test.com:8080/"&gt;http://test.com:8080/&lt;/a&gt;)，那麼取得 Context URL 的作法，在&lt;strong&gt;一般情況&lt;/strong&gt;下並不難。首先看看 ASP.NET/C# 版本：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   int idx = Request.Url.AbsoluteUri.IndexOf(Request.ApplicationPath);
   string serviceUri = Request.Url.AbsoluteUri.Substring(0, idx); // 伺服器 URL
   string applicationUri = serviceUri + Request.ApplicationPath; // 應用程式 Context URL
&lt;/pre&gt;
&lt;p&gt;JSP/Java 版本如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   int idx = request.getRequestURL().toString().indexOf(request.getContextPath());
   String serviceUri = request.getRequestURL().substring(0, idx); // 伺服器 URL
   String applicationUri = serviceUri + request.getContextPath(); // 應用程式 Context URL
&lt;/pre&gt;
&lt;p&gt;不過有&lt;strong&gt;些情況比較特殊&lt;/strong&gt;，例果透過某種 URL dispatch 的機制來存取網頁，你會發現用以上方式取得的 URL，與 Client 端發送的 URL 並不相同。我們以 IBM Tivoli Access Manager 為例，它的 URL 組成格式如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
      http://sso.com/JUNCTION/AppContext/path/to/your/page
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;sso.com: 是一個用來作 singal sign-on 的網站&lt;/li&gt;
&lt;li&gt;JUNCTION: 用來試別要將 client 端 request dispatch 到後端哪個實發處理的網站&lt;/li&gt;
&lt;li&gt;/AppContext/path/to/your/page: 後端處理要求的網頁或程式，實際位址可能是 http://192.168.1.111:8080 /AppContext/path/to/your/page 之類的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，當 Client 端發送 http://sso.com/JUNCTION/AppContext/path/to/your/page 這個請求時，經過 Tivoli Access Manager 轉送後，Server 端實際取得的服務位址是 http://192.168.1.111:8080/AppContext/path/to/your/page。&lt;/p&gt;
&lt;p&gt;為了解決這個問題，我們需要動用到 HTTP Header 裡面的一個參數 -- referer。referer 是指目前存取這個網頁，是透過哪個網頁連結過來的。有了這層認識，我們可以將上面的程式碼改成如下。 ASP.NET/C# 版本：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   if(IsPostBack) {
      idx = Request.UrlReferrer.AbsoluteUri.IndexOf(Request.ApplicationPath);
      serviceUri = Request.UrlReferrer.AbsoluteUri.Substring(0, idx); // 伺服器 URL
      applicationUri = serviceUri + Request.ApplicationPath; // 應用程式 Context URL
   }
&lt;/pre&gt;
&lt;p&gt;JSP/Java 版本如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   if(request.getParameter("IsPostBack").equals("true")){
      idx = request.getHeader("referer").indexOf(request.getContextPath());
      serviceUri = request.getHeader("referer").substring(0, idx); // 伺服器 URL
      applicationUri = serviceUri + request.getContextPath(); // 應用程式 Context URL
   }
&lt;/pre&gt;
&lt;p&gt;如果你是直接在瀏覽器的網址列輸入 URL，或是點選書籤/我的最愛直接連結，那 referer 的值會是 null。因此，我們可以透過檢查這個網頁是否是 post back 網頁，來確保 referer 有值。注意一下，JSP 裡面並沒有預設的 IsPostBack 檢查機制，你要自己做。&lt;/p&gt;
&lt;p&gt;另外，有些防火牆或防毒軟體也可能會改寫 Client 端發出的 referer，使得 Server 上取得的值為 null。若是這種情況，可以試著透過 client 端的 Javascript，取得 document.location.href 的值，將它指定給某個隱藏表單欄位，在 post 時傳給 Server 端來加以解決。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-1612957763702210167?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/1612957763702210167/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=1612957763702210167' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1612957763702210167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1612957763702210167'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/02/web-context-url.html' title='如何取得 Web 應用程式的根目錄 Context URL'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-1322083073485812906</id><published>2009-01-23T10:22:00.004+08:00</published><updated>2009-01-23T13:06:49.326+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='goodies'/><category scheme='http://www.blogger.com/atom/ns#' term='tweak'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Java SE 6 Update 10 裡面的 Nimbus Look and Feel</title><content type='html'>&lt;p&gt;Java 視窗應用程式在過去給部分人留下著刻版印象，總是認為那是跑得慢，看來醜的應用程式。不過，這真的只是刻版印象。個人在過去曾經以 Swing 套件，開發了 4 年以上的 Java Client 端應用程式，無論是在啟動速度、執行效能及視覺美觀上，Swing 介面均能達到令人滿意的程度。&lt;/p&gt;
&lt;p&gt;而事實上不論是 Sun 或是 Java 社群也一直在 Look and Feel (就相當於佈景主題--Theme 的概念) 下了相當心血。在 Java SE 6 Update 10 裡面，就包括了一個 Nimbus Look and Feel，這是一個簡潔、洗練、具現代感的 Look and Feel。我們先來看看 SwingSet3 在 Windows XP 中的呈現樣式：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3218841089/" title="Flickr 上 edwardsayer 的 SwingSet3Nimbus"&gt;&lt;img src="http://farm4.static.flickr.com/3401/3218841089_5f8fef3038.jpg" alt="SwingSet3Nimbus" height="413" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;是不是還不賴呢? 我們展現一下 Metal Look and Feel 比較一下：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3219691688/" title="Flickr 上 edwardsayer 的 SwingSet3Metal"&gt;&lt;img src="http://farm4.static.flickr.com/3424/3219691688_c17b1dfb6f.jpg" alt="SwingSet3Metal" height="413" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;除了視覺上的輕巧之外，Nimbus Look and Feel 在實質上也是相當輕巧的，因為你在畫面上所看到的各個元件，包括按鈕、捲軸、下拉選單及標題的漸層及陰影等效果，全部是用 Java 2D 向量方式 (而不是透過 bitmap 圖檔) 畫出來的，因此才占用了 56 KB 的空間。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;設定 Swing 應用程式使用 Nimbus Look and Feel&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這樣漂亮的 Look and Feel，並沒有隨著 Java SE 6 Update 10的到來，而成為 Swing 預設的 Look and Feel。開發人員必須加以設定，才能在應用程式中以它作為佈景主題。隨著需求的不同，設定方式至少有三種。&lt;/p&gt;
&lt;p&gt;在應用程式中進行設定--透過程式碼指定，你所要使用的 Look and Feel。這種方式只會將主題套用到應用程式本身，這只需要一行程式碼：&lt;/p&gt;
&lt;p&gt;UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");&lt;/p&gt;
&lt;p&gt;或者，也可以在啟動 Java 程式時，加入以下的 java 啟動參數：&lt;/p&gt;
&lt;p&gt;-Dswing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel&lt;/p&gt;
&lt;p&gt;如果你想將 Nimbus Look and Feel 設定成整台電腦中，所有 Swing 程式的預設主題，則可以在 /lib/swing.properties 這個檔案中，加入底下這行：&lt;/p&gt;
&lt;p&gt;swing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel&lt;/p&gt;
&lt;p&gt;如果上述的設定檔不存在，你可以自行新增一個。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在 jEdit 中設定 Nimbus Look and Feel&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;除了以上方式之外，有些應用程式可以透過 UI 介面，讓你設定應用程式的 Look and Feel。例如 jEdit 的這個以 Java 開發而成的編輯器，就可以在 Utilities/Global Options... 主選單所開啟的 Options 視窗中，選擇 Appearance 設定 Look and Feel。以下是套用 Nimbus 之後的外觀：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3219691584/" title="Flickr 上 edwardsayer 的 jEditNimbus"&gt;&lt;img src="http://farm4.static.flickr.com/3375/3219691584_1b053ccbe9.jpg" alt="jEditNimbus" height="393" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;附上一張預設樣式 (Metal) 作比較：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3219691536/" title="Flickr 上 edwardsayer 的 jEditDefault"&gt;&lt;img src="http://farm4.static.flickr.com/3487/3219691536_cbcb4f3253.jpg" alt="jEditDefault" height="393" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;設定 NetBeans 使用 Nimbus Look and Feel&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一直覺得 Sun 是一家有著偏執傾向的公司，他們似乎有著一種，不管別人如何批評，想要做的，便會全力以赴做到好的企業精神。因此這幾年來在 NetBeans IDE 上的進展是有目共睹的 (雖然，我還是 Eclipse 的愛用者啊! )，而我也因此相當看好 JavaFX 未來的發展…。OK，回歸正題，我想社群裡面 NetBeans 的愛好者應該也不少，要設定 NetBeans 使用 Nimbus Look and Feel 也很簡單，只要找到 NetBeans 的安裝目錄，在 etc 子目錄下的 netbeans.conf 設定檔中，找到 netbeans_default_options 設定，在設定中加上 --laf Nimbus 即可。例如，我的設定是這樣子的：&lt;/p&gt;
&lt;p&gt;netbeans_default_options="-J-Dorg.glassfish.v3.installRoot=\"C:\java\glassfish-v3-prelude-b15b\" -J-Dcom.sun.aas.installRoot=\"C:\java\glassfish-v2ur2\" -J-client -J-Xverify:none -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dnetbeans.logger.console=true -J-ea -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true &lt;span style="COLOR: #ff0000"&gt;--laf Nimbus&lt;/span&gt;"&lt;/p&gt;
&lt;p&gt;以下是套用 Nimbus 之後的外觀：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3218840973/" title="Flickr 上 edwardsayer 的 NetBeansNimbus"&gt;&lt;img src="http://farm4.static.flickr.com/3088/3218840973_7b0997853a.jpg" alt="NetBeansNimbus" height="378" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;再附上預設外觀看看：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3219691650/" title="Flickr 上 edwardsayer 的 NetBeansDefault"&gt;&lt;img src="http://farm4.static.flickr.com/3338/3219691650_dab6f58e1a.jpg" alt="NetBeansDefault" height="378" width="500"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;其實，隨著應用的不同，你很難找到一套一體適用於所有應用情境的 Look and Feel，不過，這又是另一個主題了，我就此打住。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-1322083073485812906?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/1322083073485812906/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=1322083073485812906' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1322083073485812906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1322083073485812906'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2009/01/java-se-6-update-10-nimbus-look-and.html' title='Java SE 6 Update 10 裡面的 Nimbus Look and Feel'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3401/3218841089_5f8fef3038_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-3034040454266216855</id><published>2008-12-10T08:42:00.001+08:00</published><updated>2008-12-10T08:42:22.651+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='diary'/><category scheme='http://www.blogger.com/atom/ns#' term='essay'/><title type='text'>小朋友的邏輯測驗</title><content type='html'>&lt;div&gt;小二的國語參考書上看到一個選擇題，題目是：&lt;/div&gt;
&lt;div&gt;「媽媽說，哥哥和我是她的一對寶貝 (1) 兒女 (2) 女兒」&lt;/div&gt;
&lt;div&gt;唸小二的大兒子，兒女、女兒亂猜一通…&lt;/div&gt;
&lt;div&gt;再問念小一的小兒子，他也不能正確答題。&lt;/div&gt;
&lt;div&gt;於是我問他們，說這話的是誰，大兒子就說是哥哥，小兒子也不能知道是誰說的。&lt;/div&gt;
&lt;div&gt;這時候老婆很熱心的打 pass：題目都說是媽媽說，所以就是媽媽說的。&lt;/div&gt;
&lt;div&gt;為了讓我自己不要昏死在旁邊，我只好給提示：&lt;/div&gt;
&lt;div&gt;「哥哥、姐姐、弟弟、妹妹」其中一個說的，你們選誰。&lt;/div&gt;
&lt;div&gt;這時候老婆知道我在問什麼了。&lt;/div&gt;
&lt;div&gt;二個小朋友還是一臉茫然…&lt;/div&gt;
&lt;div&gt;以前唸過皮亞傑談到識知發展的書，簡要的內容就是人的各種認知、邏輯能力，&lt;/div&gt;
&lt;div&gt;是隨著年齡而成長的。所以一些成人們認為理所當然的事，&lt;/div&gt;
&lt;div&gt;對小朋友而言，並不總是理所當然。&lt;/div&gt;
&lt;div&gt;今天這道題目，總算讓我有了另一次體驗。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-3034040454266216855?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/3034040454266216855/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=3034040454266216855' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3034040454266216855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3034040454266216855'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/12/blog-post.html' title='小朋友的邏輯測驗'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-105103067252162168</id><published>2008-11-11T14:11:00.001+08:00</published><updated>2008-11-11T17:57:49.029+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='translate'/><title type='text'>Google Translate 非官方翻譯 API</title><content type='html'>&lt;p&gt;之前為了將系統的多語化，其中一個議題就是要產生各種語系的訊息資源檔。繁簡中文的對譯，只要透過 Word 就行了，要是英日語，就得人工作業。靈機一動，想說何不借助既有的翻譯服務，為 resource 檔提供預設的簡中、英、日翻譯。&lt;/p&gt;
&lt;p&gt;就這樣，找到了一些應用 Google Translate API 的討論。試用了之後，多少都有語系編碼的問題。我最後實作了一個版本，可以在輸入正體中文時，正常產出簡中、英、日語系的翻譯。&lt;/p&gt;
&lt;p&gt;一開始我是採用 C# 語言測試，程式碼如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
public static string TranslateText(string fromLang, string toLang, string msg)
{
  string target = "http://www.google.com/translate_t?ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;text={2}&amp;amp;langpair={0}|{1}";
  string url = String.Format(target, fromLang, toLang, msg);
  WebClient webClient = new WebClient();
  webClient.Encoding = System.Text.Encoding.UTF8;
  string result = webClient.DownloadString(url);
  string sign = "&amp;lt;div id=result_box dir=\"ltr\"&amp;gt;";
  result = result.Substring(result.IndexOf(sign) + sign.Length);
  result = result.Substring(0, result.IndexOf("&amp;lt;/div"));
  return result.Replace("&amp;lt;br&amp;gt;", "\n");;
}
&lt;/pre&gt;
&lt;p&gt;後來又做了一個 Java 的版本，程式碼如下：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
public static String translateText(String fromLang, String toLang, String msg) throws IOException{
  String target = "http://www.google.com/translate_t?ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;langpair=%s|%s&amp;amp;text=%s";
  String url = String.format(target, fromLang, toLang, URLEncoder.encode(msg, "utf-8"));
  String result = getUrlContent(url);
  String sign = "&amp;lt;div id=result_box dir=\"ltr\"&amp;gt;";
  result = result.substring(result.indexOf(sign) + sign.length());
  result = result.substring(0, result.indexOf("&amp;lt;/div"));
  return result.replaceAll("&amp;lt;br&amp;gt;", "\n");
}

public static String getUrlContent(String url) throws IOException {
  URL u = new URL(url);   
  HttpURLConnection conn = (HttpURLConnection)u.openConnection();   
  conn.setRequestProperty("User-agent","Mozilla/4.0");
  conn.setRequestProperty("Content-Language","UTF-8" );
  conn.connect();
  return slurp(conn.getInputStream());            
}

public static String slurp (InputStream in) throws IOException {
  StringBuffer out = new StringBuffer();
  byte[] b = new byte[4096];
  for (int n; (n = in.read(b)) != -1;) {
    out.append(new String(b, 0, n, "UTF-8"));
  }
  return out.toString();
}
&lt;/pre&gt;
&lt;p&gt;測試程式長得像這樣：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
public static void main(String []argv) throws IOException{
  System.out.println(GoogleTranslate.translateText("zh-TW", "zh-CN", "書不同文、車不同軌、世界不大同!"));
  System.out.println(GoogleTranslate.translateText("zh-TW", "en", "書不同文、車不同軌、世界不大同!"));
  System.out.println(GoogleTranslate.translateText("zh-TW", "ja", "書不同文、車不同軌、世界不大同!"));          
}
&lt;/pre&gt;
&lt;p&gt;稍微說明一下我的測試心得。&lt;/p&gt;
&lt;p&gt;首先，就是使用 Google Translate 時，最好是明確指定你所用的輸入編碼及輸出編碼，即上面 URL 連結中的 ie=UTF-8&amp;amp;oe=UTF-8。若不明確指定，Google 可是會依據你的輸入語言，而決定輸出編碼。例如，你輸入的語言是 "zh-CN"，它預設會採用 gb2312 編碼回應。這會造成處理上的困擾。&lt;/p&gt;
&lt;p&gt;其次，由於 .NET 與 Java 平台內建皆採用 UTF-8 編碼，因此在我們指定輸入編碼及輸出編碼時，當然是優先考量 UTF-8。&lt;/p&gt;
&lt;p&gt;最後，如果你用 Eclipse 做測試，你可能會發現 console 裡有部分亂碼。請依照下圖，在 Run/Run Configurations... 裡面做設定，將 Console Encoding 指定為 UTF-8：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3020810615/" title="Flickr 上 edwardsayer 的 eclipse-console-utf8"&gt;&lt;img src="http://farm4.static.flickr.com/3277/3020810615_99105bf3fc_o.png" style="DISPLAY: inline" height="576" alt="eclipse-console-utf8" width="731"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最後就能產出正常的顯示了。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3020810629/" title="Flickr 上 edwardsayer 的 eclipse-console-utf8-2"&gt;&lt;img src="http://farm4.static.flickr.com/3138/3020810629_1e73eb99dd_o.png" alt="eclipse-console-utf8-2" height="133" width="546"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-105103067252162168?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/105103067252162168/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=105103067252162168' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/105103067252162168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/105103067252162168'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/11/google-translate-api.html' title='Google Translate 非官方翻譯 API'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2563880694159473625</id><published>2008-11-07T13:49:00.001+08:00</published><updated>2008-11-07T13:49:26.203+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='foxsaver'/><category scheme='http://www.blogger.com/atom/ns#' term='goodies'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='screensaver'/><title type='text'>正妹牆螢幕保護程式</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/3009925524/" title="Flickr 上 edwardsayer 的 foxsaver-beauty1"&gt;&lt;img src="http://farm4.static.flickr.com/3240/3009925524_edd3c8070a_o.png" style="DISPLAY: inline; FLOAT: right" height="590" alt="foxsaver-beauty1" width="277"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;辦公室前面擺了一個 40 幾吋的電漿螢幕，放置不用殊為可惜。與同事閒聊之際，突然靈機一動，何不拿來展示正妹牆，24 下時輪播，慰勞整天辛勞的宅男工程師。&lt;/p&gt;
&lt;p&gt;有了這個想法，首先想到了就是要找個能播放 media rss 的螢幕保護程式。試了幾個，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pack.google.com/screensaver.html"&gt;Google 螢幕保護程式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuparadigm.com/Products/Toys/RssScreensaver/"&gt;NuParadigm&lt;/a&gt;, 以及&lt;/li&gt;
&lt;li&gt;&lt;a href="http://marrowalk.blogspot.com/2008/09/25.html" class="taggedlink" rel="nofollow"&gt;marrowalk的雜記本: 25個超酷的螢幕保護程式&lt;/a&gt;裡面介紹的一些&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;效果都出不來。決定拿 &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5276"&gt;FoxSaver&lt;/a&gt; 一試 -- 嘿，別看太久，年輕人會流鼻血的。&lt;/p&gt;
&lt;p&gt;FoxSaver 是 Firefox 的一個 Extension，可以把 Firefox 變成螢幕保護程式。從它的選項來看，圖片來源可以來自本機目錄，RSS 或一般網頁。由於這個 Extension 還在實驗中，在 addons.mozilla.org 網站上需要登入才能安裝。我在安裝之後，使用上是沒有大問題。重點來了，怎麼設定 &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5276"&gt;FoxSaver&lt;/a&gt; 讀取正妹牆 RSS 呢。一圖勝千言，請見右圖 。&lt;/p&gt;
&lt;p&gt;如此之後，在 Firefox 狀態列上的 FoxSaver 按鈕上點右鍵，選擇「FoxSaver 開始」就行了。&lt;/p&gt;
&lt;p&gt;當然，也有人推薦用 &lt;a href="http://www.cooliris.com/"&gt;PicLens/Cooliris&lt;/a&gt; 來觀正妹牆，除了可以自己操刀，將正妹們拉遠拉近觀看外(是不是第一次感受到那種呼之即來，揮之即去的操作感 &amp;gt;_&amp;lt;|||)，要透過 Cooliris 來達到類似螢幕保護程式的效果，記得按一下三角型的播放鈕，這 -- 不就變成美女自動送上門的桌上版了嗎。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2563880694159473625?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2563880694159473625/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2563880694159473625' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2563880694159473625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2563880694159473625'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/11/blog-post.html' title='正妹牆螢幕保護程式'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-8699660344773970672</id><published>2008-10-15T00:02:00.001+08:00</published><updated>2008-10-16T08:03:12.232+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jsp'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>glassfish-v2 JSP request 中文參數亂碼解法</title><content type='html'>&lt;p&gt;最近幾天用 Microsoft Visual Web Developer 2008 Express Edition 練習 ASP.NET + ADO.NET，順便把 Java 陣營兩大 IDE Eclipse 及 NetBeans 拿來比較一下開發的易用性…&lt;/p&gt;
&lt;p&gt;心得是，以 NetBeans 用 JSF + JPA 開發網站，開發的效率並不下於 ASP.NET + ADO.NET。而 Eclipse 的 JPA 工具(稱為 Dali Java Persistence Tool) 的功能其實也相當完善，例如，它可以讓你由 Java class 產生 db table，也可以讓你由 table 產生 entity class。唯一在使用性上不足之處，是 Eclipse 出廠設定較 NetBeans 薄弱。例如，為了使用 JPA，你必須自行下載一個 JPA 的一個實作，而為了使用 JSF，你也必須自行下載一個 JSF 的一個實作。下載後還要自行設定… 需要看一點功夫才設定的起來。而 NetBeans 如果下載的是 Web &amp;amp; Java EE 版，預設就能直接開發 JSF + JPA 程式，甚至連範例專案都含在裡面，deploy 一下，直接就能 run 了。&lt;/p&gt;
&lt;p&gt;以上都是雜話，以下是正文，但正文不會很多。&lt;/p&gt;
&lt;p&gt;在測試 NetBeans 開發 Web 網站時，遇到一件有趣的事。就是以 NetBeans JSP web application 的預設組態，deploy 到 glassfish-v2 上，輸入中文時，取得的資料會是亂碼。但若是以 JSF 來開發 web application 便不會有中文亂碼的問題。&lt;/p&gt;
&lt;p&gt;glassfish 中文亂碼的問題，可參考 &lt;a href="http://wiki.glassfish.java.net/Wiki.jsp?page=FaqHttpRequestParameterEncoding"&gt;FaqHttpRequestParameterEncoding&lt;/a&gt; 或 &lt;a href="http://docs.sun.com/app/docs/doc/820-4496/beafw?a=view"&gt;Servlet Character Encoding&lt;/a&gt;，在 sun-web.xml 中加入 default-charset="UTF-8" 得到解決，如下所示：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
   &amp;lt;sun-web-app&amp;gt;
     &amp;lt;locale-charset-info default-locale=""&amp;gt;
       &amp;lt;locale-charset-map locale="" charset=""/&amp;gt;
       &amp;lt;parameter-encoding default-charset="UTF-8"/&amp;gt;
     &amp;lt;/locale-charset-info&amp;gt;
   &amp;lt;/sun-web-app&amp;gt;
&lt;/pre&gt;
&lt;p&gt;(注意，在 NetBeans 裡面，預設將 JSP 及 Java 檔都以 UTF-8 存檔，且 JSP 皆加入 &amp;lt;%@page pageEncoding="UTF-8"%&amp;gt; 指示)。&lt;/p&gt;
&lt;p&gt;但 JSF 沒有中文亂碼問題，雖然這是好事，但反道讓我有些不解。用 Google 查詢一下，原來在 JSF 規範裡面有特別提到要如何解析當前 request 參數的編碼，&lt;a href="http://apptaro.seesaa.net/article/41505341.html"&gt;Tips for JSF character encoding&lt;/a&gt; 有精要的描述。有了這些資訊，便不需再透過撰寫 filter 來解決編碼問題了。&lt;/p&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;&lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;&lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/glassfish" class="ztag" rel="tag"&gt;glassfish&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/java" class="ztag" rel="tag"&gt;java&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/jsf" class="ztag" rel="tag"&gt;jsf&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/jsp" class="ztag" rel="tag"&gt;jsp&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/programming" class="ztag" rel="tag"&gt;programming&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-8699660344773970672?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/8699660344773970672/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=8699660344773970672' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8699660344773970672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8699660344773970672'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/10/glassfish-v2-jsp-request.html' title='glassfish-v2 JSP request 中文參數亂碼解法'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-3203479904745440984</id><published>2008-07-09T00:39:00.000+08:00</published><updated>2008-07-09T00:54:20.539+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='google trends'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>使用 Google Trends, 你有進行基值/基期校正嗎?</title><content type='html'>&lt;p&gt;因為在 iThome 看到一位與我有一面之緣、熱衷 Flex 的高手，透過分析 Google Trends 資料，寫了一篇名為「RIA四雄群起：以Google Trends評析現有RIA四大技術(Flex、Silverlight、JavaFX、Curl)」的 blog。由於其中各種技術熱門程度的差異實在太大，激起了我進一步自行探索的動力。&lt;/p&gt;
&lt;p&gt;第一件使我產生懷疑的是，文中指出 Flex 技術是 2004 年發行 1.0 版，我到 Wikipedia 查了一下資料，是 2004 年 3 月。那時候 Flex 還是 Macromedia 所提出的一個 Server 端方案，需配合貴死人的 Server 端執行。而由圖一可以明顯看出，Flex 的趨勢線在 2004 年初就一直處於高檔，直覺跟…好吧--年紀--告訴我這不合理。&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/2649460535/" title="Flickr 上 edwardsayer 的 ria-3"&gt;&lt;img src="http://farm4.static.flickr.com/3259/2649460535_021607a888_o.png" alt="ria-3" height="302" width="589"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center"&gt;圖一：未經校正的 Google Trends 查詢：Flex, Silverlight, JavaFX, Curl&lt;/p&gt;
&lt;p&gt;而第二件讓我覺得更不合理的是，如果你直接透過 Google &lt;a href="http://www.google.com.tw/search?hl=zh-TW&amp;amp;ie=UTF-8&amp;amp;&amp;amp;q=Curl"&gt;查詢&lt;/a&gt; Curl，可以發現十之八九都與 RIA 無關。這樣的查詢流量怎能將它全部歸到 Curl for RIA 這一塊呢。&lt;/p&gt;
&lt;p&gt;我相信 Flex 這將近 0.9 的 Search Volumn Index，並非指 Macromedia/Adobe 的 Flex 技術；同樣的，Curl 大多的查詢流量也與 RIA 無關。為了進行檢驗，我將查詢語句作了一些修正，以期找出較具代表性的指標。新的查詢為：Macromedia Flex, Microsoft Silverlight, Sun JavaFX, Adobe Flex。&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center"&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/2650291462/" title="Flickr 上 edwardsayer 的 ria-4"&gt;&lt;img src="http://farm4.static.flickr.com/3117/2650291462_2a164eb09d_o.png" alt="ria-4" height="326" width="597"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center"&gt;圖二：經過校正的 Google Trends 查詢：Macromedia Flex, Microsoft Silverlight, Sun JavaFX, Adobe Flex&lt;/p&gt;
&lt;p&gt;這個查詢中，Flex 的熱門程度可用 Macromedia Flex + Adobe Flex 來代表。基本上可看出，在 2004 年 3 月以前，少有人關注 Flex。而 Microsoft Silverlight 的聲勢，"有段時間" 其實並不小於 Macromedia/Adobe Flex，那 Sun 的 JavaFX，就趴在地上了。&lt;/p&gt;
&lt;p&gt;不過，究竟一般網民在查詢時，並不會特別以 Adobe Flex、Microsoft Silverlight 這樣的組字方式去下。以上，我所要說明的是，在以 Google Trends 進行分析時，得對基期或基值進行校正。透過第二個查詢我們已經證明 2004 年 3 月前的 Flex 流量，不能算是 Flex for RIA 這一塊的流量。如果將圖一 Flex 的流量值向下平移 0.9 單位，可以看出 Flex 對 Silverlight 的比值將接近圖二所示。&lt;/p&gt;
&lt;p&gt;行文至此，是不是可以建議 Google Trends 提供類似基期/基值校正的功能。不然，就趕快把 Google Treands 的 API 給 release 出來吧!&lt;/p&gt;
&lt;p&gt;相關連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.google.com/trends"&gt;Google Trends&lt;/a&gt;: http://www.google.com/trends&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.adobe.com/devnet/flex/"&gt;Flex&lt;/a&gt;: http://www.adobe.com/devnet/flex/&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/silverlight/"&gt;Silverlight&lt;/a&gt;: http://www.microsoft.com/silverlight/&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sun.com/software/javafx/"&gt;JavaFX&lt;/a&gt;: http://www.sun.com/software/javafx/&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.curl.com/"&gt;Curl&lt;/a&gt;: http://www.curl.com/&lt;/li&gt;
&lt;li&gt;Google Trends API coming soon: &lt;a href="http://news.cnet.com/8301-10784_3-9828916-7.html"&gt;http://news.cnet.com/8301-10784_3-9828916-7.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;iThome 原作者文章: &lt;a href="http://ithelp.ithome.com.tw/question/10005797"&gt;RIA四雄群起：以Google Trends評析現有RIA四大技術(Flex、Silverlight、JavaFX、Curl)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/analysis" class="ztag" rel="tag"&gt;analysis&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/google" class="ztag" rel="tag"&gt;google&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/google+trends" class="ztag" rel="tag"&gt;google trends&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/statistics" class="ztag" rel="tag"&gt;statistics&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/web" class="ztag" rel="tag"&gt;web&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-3203479904745440984?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/3203479904745440984/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=3203479904745440984' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3203479904745440984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3203479904745440984'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/07/google-trends.html' title='使用 Google Trends, 你有進行基值/基期校正嗎?'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-867512582992660711</id><published>2008-05-08T00:00:00.002+08:00</published><updated>2009-04-02T21:36:53.021+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pmog'/><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>PMOG 簡易練功外掛</title><content type='html'>&lt;p&gt;&lt;b&gt;&lt;font color=red&gt;(2009/04/02)警告--本文一開始只是作為概念性驗證， 現在 PMOG 已針對這裡所提供的方法作出防範，勿再使用本文所提供之方法，以免告成帳號被刪 :( &lt;/font&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;前一陣子收到了 PMOG 的啟用信，便依照「電腦玩物」的說明，趁著工作空檔試玩了一下。突然想到，在一般的 game 系統，都有一些超級玩家或高手，懂得利用外掛程式來練功，那這個 client 端基於 Firefox 的遊戲平台，要寫一個練功的外掛應該也不是難事吧!&lt;/p&gt;
&lt;p&gt;PMOG 平台裡面，透過 Datapoint 來代表玩家的經驗值。增加 Datapoint 最簡單的方式，就是瀏覽不同網域的網頁。如果我們要透過這樣的規則來練功，代表我們每天要想辦法去到不同的網域。而哪來那麼多不同的網域呢來瀏覽呢？&lt;/p&gt;
&lt;p&gt;透過 Google 查詢，我找到一個 "Random Link" 連結，每當你瀏覽這個連結時，它會將你導到不同的網址。因此，你可以把這個連結放到 Firefox 的書籤工具列，每次按一下，就會連到不同的網頁。&lt;/p&gt;
&lt;p&gt;接下來，就是想辦法讓上面的程序自動化。有時間、有時間精神的高手可以寫個 Firefox Extension。比較偷懶一點，就可以透過 Greasemonkey script 來達到這個功能。以下是我所使用的 user script：&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
// ==UserScript==
// @name           automatic random link
// @namespace      http://isong.blogspot.com/
// @description    visit random web pages automatically
// @include        *
// ==/UserScript==

setTimeout(function() {
  location.href = "http://random.yahoo.com/bin/ryl?"  + new Date().getTime();
}, 5000);                                
&lt;/pre&gt;
&lt;p&gt;只要在 Greasemonkey 中增加此用戶腳本，然後在想練功時啟用此腳本，就可以看到你的 Datapoint 值不斷增加囉!&lt;/p&gt;
&lt;p&gt;相關連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pmog.com/"&gt;PMOG&lt;/a&gt;: Passively Multiplayer Online Game 官方首頁&lt;/li&gt;
&lt;li&gt;&lt;a href="http://playpcesor.blogspot.com/2008/02/firefoxpmog.html"&gt;電腦玩物&lt;/a&gt;: 現實網路尋寶冒險，Firefox上的被動式多人線上遊戲：PMOG -- 完善的 PMOG 遊戲說明&lt;/li&gt;
&lt;li&gt;&lt;a href="http://zh.wikipedia.org/w/index.php?title=Greasemonkey&amp;amp;variant=zh-tw"&gt;Greasemonkey&lt;/a&gt;: 可自訂你的網頁瀏覽體驗&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/zh-TW/firefox/addon/748"&gt;Greasemonkey Firefox 附加元件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://userscripts.org/"&gt;Userscripts.org&lt;/a&gt;: 可在這裡找到許多給 Greasemonkey 使用的用戶腳本&lt;/li&gt;
&lt;li&gt;&lt;a href="http://random.yahoo.com/bin/ryl"&gt;Random Link&lt;/a&gt;: Yahoo! 所提供的隨機網頁連結&lt;/li&gt;
&lt;/ul&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;&lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;&lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/firefox" class="ztag" rel="tag"&gt;firefox&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/funny" class="ztag" rel="tag"&gt;funny&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/game" class="ztag" rel="tag"&gt;game&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/greasemonkey" class="ztag" rel="tag"&gt;greasemonkey&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/pmog" class="ztag" rel="tag"&gt;pmog&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-867512582992660711?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/867512582992660711/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=867512582992660711' title='15 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/867512582992660711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/867512582992660711'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/05/pmog.html' title='PMOG 簡易練功外掛'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-686473164183557433</id><published>2008-04-21T23:33:00.000+08:00</published><updated>2008-04-22T20:17:05.945+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='site news'/><category scheme='http://www.blogger.com/atom/ns#' term='goodies'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>用 JavaScript 來修飾你的超連結</title><content type='html'>&lt;p&gt;網頁之間的互相引用、評論，是當代網誌的形式之一，而造就的結果就是正文之中充斥著超連結。
&lt;br/&gt;
&lt;br/&gt;
這樣的書寫風格本身並沒有所謂的好或不好。在我的日誌中，也存在不少此類用法。問題是，如果同一篇日誌中，重複提及一個特定的網頁，而該網頁又值得透過超連結參引，那麼重複編製超連結的動作，也會令人覺得繁瑣。
&lt;br/&gt;
&lt;br/&gt;
為此，我想到設定一種 "形式"，再加上 JavaScript，來為正文中的特定字眼加上連結。&lt;/p&gt;
&lt;p&gt;構想是，在每篇網誌的最後，加上一段 "相關連結" 或 "參考資料"，段落名稱是什麼不重要，重點是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;將連結以無序清單的形式標明，每一清單項目以連結開頭&lt;/li&gt;
&lt;li&gt;以冒號+空白 (&lt;code&gt;": "&lt;/code&gt;) 來區分連結及解說文字，例如：
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://isong.blogspot.com/"&gt;愛頌過生活&lt;/a&gt;: 就是過日子，人生不需太多大道理!&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.w3.org/DOM/"&gt;DOM&lt;/a&gt;: Document Object Model (DOM); W3C 的官方說明&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上例中的 "愛頌過生活" 及 "DOM" 字串，會被當作匹配條件，在正文的段落 (&amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt; 包起來的部分) 中，比對相符的字眼。若出現相符的字串，將被 JavaScript 套上超連結。&lt;/p&gt;
&lt;p&gt;用來轉換文字成超連結的 JavaScript 程式碼如下：&lt;/p&gt;
&lt;pre xml:space="preserve" class="prettyprint"&gt;
&amp;lt;script type="text/javascript"&amp;gt;
var init = {
  cmds: [],
  run: function(){
    for(i = 0; i &amp;lt; this.cmds.length; i++)
      this.cmds[i]();
  }
}

function getText(anchor){
   return anchor.text ? anchor.text : anchor.innerText;
}

function fixPostElements(){
   var uls = document.getElementsByTagName("ul");
   for(var i = 0; i &amp;lt; uls.length; i++)
      insertResourceLink(uls[i].parentNode)
}
function insertResourceLink(element) {
  var links= {};
  var lis = element.getElementsByTagName("li");
  for (var i = 0; i &amp;lt; lis.length; i++){
    if(lis[i].innerHTML.indexOf(": ") != 0){
      as = lis[i].getElementsByTagName("a");
      for(j = 0; j &amp;lt; as.length; j++)
        links[getText(as[j])] = as[j].href;
    }
  }
  var ps = element.getElementsByTagName("p");
  for(key in links) {
    var regKey = new RegExp(key, "g");
    for(var i = 0; i &amp;lt; ps.length; i++) {
      ps[i].innerHTML = ps[i].innerHTML.replace(regKey,
         "&amp;lt;a href="+ links[key] +"&amp;gt;" + key +"&amp;lt;/a&amp;gt;");
    }
  }
}
init.cmds.push(fixPostElements);
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;將上面的程式碼置於 HTML 的 head 區塊，在 body tag 中加上 onload="init.run()"，於撰寫網誌時採用本文規範的形式，即可達所述的效果。&lt;/p&gt;
&lt;p&gt;一篇符合本文形式規範的網誌文章，可參考 "&lt;a href="http://isong.blogspot.com/2008/04/prism-for-firefox-3-beta-5-url-link.html"&gt;PRISM for Firefox 3 beta 5 url link opening issue&lt;/a&gt;"。事實上，筆者正是在撰寫該文時，因對重複的超連結編製深感不耐，才產生此構想的。&lt;/p&gt;
&lt;p&gt;附帶一提，如果讀者採用 Google Reader 或其他 RSS 閱讀軟體，那麼你將無法看到此 JavaScript 的效果，因為 RSS feed 中並不含 JavaScript 轉譯碼… 這樣的設計，或許可以解釋為：「為親自造訪本站的讀者，所提供的一點加值服務 ^__^」。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-686473164183557433?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/686473164183557433/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=686473164183557433' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/686473164183557433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/686473164183557433'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/04/javascript-html.html' title='用 JavaScript 來修飾你的超連結'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-3732035004142308180</id><published>2008-04-18T06:51:00.001+08:00</published><updated>2008-04-18T08:37:14.310+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='tweak'/><category scheme='http://www.blogger.com/atom/ns#' term='bug fix'/><category scheme='http://www.blogger.com/atom/ns#' term='prism'/><category scheme='http://www.blogger.com/atom/ns#' term='firefox 3'/><title type='text'>Prism for Firefox 3 beta 5 url link opening issue</title><content type='html'>&lt;p&gt;今天將自用的電腦換成還在 beta 中的 Firefox 3，順手就裝了可以「將網頁變成桌面程式」的擴充套件 Prism。它的功能一如產品網頁描述，可以在桌面產生一個 URL 連結，也可以顯示 tray icon。&lt;/p&gt;
&lt;p&gt;我首先轉換的應用網站便是 Gmail，轉換成完後，點選桌面 Gmail 捷徑，帶出一個沒有任何修飾 (不會讓你分心) 的 Gmail 應用程式視窗。怪的是，在我的環境 Windows XP + 這樣的組合下，在 Prism 的 Gmail 網頁中開啟 URL 連結時，它開啟的外部瀏覽器竟是 IE，而不是我所期望的 Firefox。在 Firefox 「工具/選項/進階」中將 firefox 設定成系統預設瀏覽器也沒有用。&lt;/p&gt;
&lt;p&gt;本想試試 Linky 這個專門用來改進連結開啟方式的擴充套件，但在 Prism 中卻無法安裝。我沒去細究那是 Prism 本身，還是 Linky 或 Firefox bata 3 的版本關係，總之就是不能用。&lt;/p&gt;
&lt;p&gt;查了一下 firefox command line arguments, 看到了 -setDefaultBrowser 這個選項，可以將 firefox 設定成系統預設瀏覽器。於是我試著在 DOS 指令視窗中輸入以下指令：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;C:\&amp;gt;cd "\Program Files\Mozilla Firefox 3 Beta 5"
&lt;br/&gt;
C:\Program Files\Mozilla Firefox 3 Beta 5&amp;gt;firefox -setDefaultBrowser&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;沒想到這麼一來，當我再次於 Prism 的 Gmail 網頁中開啟連結時，竟然就能將連結開啟於 Firefox 中了。&lt;/p&gt;
&lt;p&gt;相關連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://labs.mozilla.com/2007/10/prism/"&gt;Prism&lt;/a&gt;: 將網頁變成桌面程式&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mail.google.com/mail/"&gt;Gmail&lt;/a&gt;: Google 所推出的 webmail 服務&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.mozilla.org/en/docs/Command_Line_Options"&gt;firefox command line arguments&lt;/a&gt;: 說明 firefox 啟動參數&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gemal.dk/mozilla/linky.html"&gt;Linky&lt;/a&gt;: firefox 延伸套件&lt;/li&gt;
&lt;/ul&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/bug+fix" class="ztag" rel="tag"&gt;bug fix&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/firefox" class="ztag" rel="tag"&gt;firefox&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/firefox+3" class="ztag" rel="tag"&gt;firefox 3&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/prism" class="ztag" rel="tag"&gt;prism&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/tweak" class="ztag" rel="tag"&gt;tweak&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-3732035004142308180?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/3732035004142308180/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=3732035004142308180' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3732035004142308180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/3732035004142308180'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/04/prism-for-firefox-3-beta-5-url-link.html' title='Prism for Firefox 3 beta 5 url link opening issue'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-1758576466416143665</id><published>2008-04-12T17:34:00.000+08:00</published><updated>2008-04-12T17:29:04.201+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='miro'/><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='bug fix'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Miro 1.2.* 無法啟動的 Bug 及 Quick Dirty Fix</title><content type='html'>&lt;p&gt;&lt;a href="http://www.getmiro.com/"&gt;Miro&lt;/a&gt; 這套以 XUL Runtime 為基礎的網路影片撥放軟體，有著優良的使用介面及易用豐富的影片搜尋功能，在網路上已經有不少 &lt;a href="http://blogsearch.google.com.tw/blogsearch?hl=zh-TW&amp;amp;ie=UTF-8&amp;amp;um=1&amp;amp;q=miro&amp;amp;btnG=搜尋網誌&amp;amp;lr=lang_zh-TW"&gt;blogger 介紹&lt;/a&gt;過，我就不再贅言。&lt;/p&gt;
&lt;p&gt;如果你也是 &lt;a href="http://www.getmiro.com/"&gt;Miro&lt;/a&gt; 的愛好者，或是看過介紹後躍躍欲試，卻同我一樣遭遇以下畫面：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/2407398674/" title="Flickr 上 edwardsayer 的 Miro StartUp Error"&gt;&lt;img src="http://farm4.static.flickr.com/3039/2407398674_57349bc143_m.jpg" alt="Miro StartUp Error" height="150" border="0" width="240"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;除了程式視窗外框、骨架外，所有內容都沒有顯示出來。那麼底下提供一個 quick dirty fix，或許可以解你想看影片的燃眉之急。&lt;/p&gt;
&lt;p&gt;首先，找到 C:\Program Files\Participatory Culture Foundation\Miro\components\pybridge.py 這個檔案。找到其中一段程式碼：&lt;/p&gt;
&lt;pre xml:space="preserve"&gt;
   keyElement.setAttribute('keytext', _('Spacebar'))
&lt;/pre&gt;
&lt;p&gt;由於這行程式中的 _(Spacebar) 在執行期會運算成 "空白鍵" 這個中文字串，進一步造成 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128) 的錯誤。因為並未深入了解 Miro 完整的 localization 架構，這是一個目前看來我無法完整解決的問題。因此我採用一個 quick dirty fix，將上面那行改成如下：&lt;/p&gt;
&lt;pre xml:space="preserve"&gt;
   keyElement.setAttribute('keytext', 'Spacebar')
&lt;/pre&gt;
&lt;p&gt;注意，由於程式是 python 語言，因此請不要改變以上程式碼的縮排。儲存檔案，重新開啟 Miro，那麼你應該可以重新找尋、欣賞喜好的影片了。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/edwardsayer/2407398696/" title="Flickr 上 edwardsayer 的 Miro OK Now"&gt;&lt;img src="http://farm4.static.flickr.com/3194/2407398696_9550237aa3_m.jpg" alt="Miro OK Now" height="183" border="0" width="240"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note: 本方法僅在 Window Miro 1.2, 1.2.2 版上試驗過。&lt;/p&gt;
&lt;p xmlns="" class="zoundry_raven_tags"&gt;
  &lt;!-- Tag links generated by Zoundry Raven. Do not manually edit. http://www.zoundryraven.com --&gt;
  &lt;span class="ztags"&gt;&lt;span class="ztagspace"&gt;Technorati&lt;/span&gt; : &lt;a href="http://www.technorati.com/tag/bug" class="ztag" rel="tag"&gt;bug&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/bug+fix" class="ztag" rel="tag"&gt;bug fix&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/miro" class="ztag" rel="tag"&gt;miro&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/video" class="ztag" rel="tag"&gt;video&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/web" class="ztag" rel="tag"&gt;web&lt;/a&gt;&lt;/span&gt; 
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-1758576466416143665?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/1758576466416143665/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=1758576466416143665' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1758576466416143665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1758576466416143665'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2008/04/miro-12-bug-quick-dirty-fix_12.html' title='Miro 1.2.* 無法啟動的 Bug 及 Quick Dirty Fix'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3039/2407398674_57349bc143_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-2993449218720312221</id><published>2007-12-19T15:27:00.000+08:00</published><updated>2008-04-18T19:12:20.775+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='essay'/><title type='text'>該學那些程式語言2008版</title><content type='html'>&lt;p&gt;這主題向來是討論區上常被提出的問題，一言以蔽之，選擇最好的或最受歡迎的…
&lt;br/&gt;
&lt;br/&gt;
選擇最受歡迎的，站在你自己的角度來看，它可以提高你在市場上的身價，讓你找的到工作，可以填飽肚子。而站在別人的角度來講，你開發出來的系統容易讓別人接手，開發系統時可用的支援較多，市場的接受度較高，不用重新教育使用者。
&lt;br/&gt;
&lt;br/&gt;
選 擇最好的，一方面是可以接觸新思維，提供不同的視野。另一方面，則是期望有一天，最好的可以變成最受歡迎的。而早期投入者，多少可以收到 "傳教士" 般的尊崇待遇。還記得以前 XML 剛出來時，大力推廣 XML 的勞虎，在網路上廣泛傳送其免費電子書《無廢話 XML》，而今多少學習 XML 的網民，還是感念其恩德啊!
&lt;br/&gt;
&lt;br/&gt;
那麼，以下便是我的選擇。我會說明其主要應用，及個人對它的觀感。
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight: bold;"&gt;最受歡迎：&lt;/span&gt;
&lt;br/&gt;
&lt;br/&gt;
C/C ++：這應該是正統資訊工程科系都必修的語言吧，它的應用不但能讓你直指核心(C)，也能讓你站在物件的具像高度(C++)，思考系統的構成。像是系統程 式、原生應用程式、軔體、Driver 等，皆是 C/C++ 應用所及之處。尤其台灣電子產業相對發達，在各種掌上型、智慧型裝置不斷推陳出新的今天，對C/C++的人力資源有高度需求。不過這個語言(尤其 C++)因為承載太多歷史包袱，各種實作變體太大，開發時常需用很多 tricks，在應用時需要付出較多心力，在程式語言本身及各種環境歧異的細節上!
&lt;br/&gt;
&lt;br/&gt;
Java：如果你唸資工 系，但學校 C/C++ 課程非必修，那麼至少 Java 是必修課程吧! Java 除了較少用在系統程式外，其他領域幾乎都占有一席之地。由於 Java 具有良好的物件導向基礎，當代許多企業應用皆採 Java Solution，尤其是在 SOA/ESB/EAI 等領域。採用 Java Solution 的好處是自由度高，但缺點就是很多事情沒有標準作法，或支援標準作法的解決方案太多，往往要花費不少時間在選擇如何架構系統上。
&lt;br/&gt;
&lt;br/&gt;
C# &amp;amp; VB.NET：這能讓你賺錢! 可以讓你快速的寫出漂漂亮亮的應用程式! 能讓你與微軟的企業系統做 完美的結合。像是 BI(OLAP、Reporting、Data Mining)那一塊，是 Java 在應用上比較需要費心的。而 .NET 相對於 Java 較緊緻的技術堆疊，能讓開發者較專注於應用程式的開發上。缺點是，離開了微軟平台的世界，就幾無用武之地。
&lt;br/&gt;
&lt;br/&gt;
PHP/Ruby：如果你想 run 自己的 business，或想建立一個像黑米、放P、挖女孩那樣的網站，相信我，這是一個很好的選擇。不過由於目前這兩個語言主要用途只在 Web 開發上，因此特別要注意典範的轉移，或是其原來專精的部分不再具有優勢。
&lt;br/&gt;
&lt;br/&gt;
就典範轉移：我的意思是，PHP/Ruby 除了在 Web 開發上已有成功的 killer apps 之外，其實它們能做的事，其他語言或平台也都能做，除非它們能在別的應用領域一樣成功，否則對其未來發展仍是一項危機。而就 "其原來專精的部分不再具有優勢"，這並非不可能發生，請見以下的 ECMAScript 說明。但好消息是，至少在 2007 年，這兩個語言的排名在 &lt;a href="http://www.tiobe.com/tpci.htm"&gt;TIOBE&lt;/a&gt; 上的排名都是往上升的。
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight: bold;"&gt;最好的：&lt;/span&gt;
&lt;br/&gt;
&lt;br/&gt;
Python： 真正的跨平台，除了跨 Windows, Linux 這類原生作業平台外，它也有 Java 及 .NET 虛擬機器的移植版本。在 Java 與 .NET 競相誇炫平台能力之際，Python 仍能堅守語言本身的原味之美，是令人讚賞的。也因如此，Python 的應用領域眾多，從 Web、文字及檔案處理、科學到研究等，幾乎無所不包。事實上，很多研究平台內定的 scripting language 就是 python，像是用於統計的 SPSS、用於資料探勘的 Clementine 等。
&lt;br/&gt;
&lt;br/&gt;
D：被視為是 "C++ done right!" 的一個程式語言，支援了許多 C++/Java/C# 共有的特徵(OOP)，但卻也有些特徵是其他語言所欠缺(或尚在研議中)像 Out function parameters,Nested functions,Function literals,Closures,Resizeable arrays...。在現今 VM 當道的年代，D 仍編譯為 native executable，可見其定位，是比較接近 C/C++ 的。也就是適合拿來撰寫系統程式、原生應用程式、伺服器程式，以及網路應用程式等。不過，對於 D 被廣泛接受仍有重大疑慮，因直至目前為止還不知有任何較大型的專案採用 D 語言開發。相較於 Ruby 也沒有像 &lt;a&gt;RoR&lt;/a&gt; 那樣的殺手級應用出現。
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight: bold;"&gt;最受歡迎+最好的：&lt;/span&gt;
&lt;br/&gt;
&lt;br/&gt;
ECMAScript&lt;span class="wikiword"&gt;/JavaScript&lt;/span&gt;/ActionScript：JavaScript 與 ActionScript 都朝 ECMAScript 標準靠攏。本來 &lt;span class="wikiword"&gt;JavaScript&lt;/span&gt; 是被某些人唾棄的一無是處，以為它只會在瀏覽器上作作表面功夫的語言，但一朝 Ajax 的應用得到普遍的喜愛&lt;span class="wikiword"&gt;，JavaScript&lt;/span&gt; 的行情也就跟著水漲船高。但如果只是這樣，對於 ECMAScipt 最新標準的推廣倒不見得有多大助益。特別是後來 &lt;span class="wikiword"&gt;ActionScript&lt;/span&gt; 也遵循 ECMAScript 標準，而且號稱 &lt;span class="wikiword"&gt;ActionScript&lt;/span&gt; 3.0 是非常遵循，這就好玩了。因為 &lt;span class="wikiword"&gt;ActionScript&lt;/span&gt; 是應用在 Flex/Flash player 中，而瀏覽器中主要執行的指令語言是 &lt;span class="wikiword"&gt;JavaScript&lt;/span&gt;， 而這兩者都是當代 Thin Client/RIA 的主流，因此我們可以說 ECMAScript Family 幾乎已成為 Universal Client Lauguage。
&lt;br/&gt;
&lt;br/&gt;
再者，認為 JavaScript 只會在瀏覽器上作作表面功夫其實並非事實。早期 Netscape Enterprise Server 及 BroadVision One-to-One Server，在 JSP 尚未出現前，伺服器上執行的指令語言就是 JavaScript。而前文提到現在是 VM 當道的年代，現在 ActionScript 的 engine 也已成為一個 VM，叫 AVM，且已貢獻給 Mozilla，成立 Tamarin 專案，將來若用於 Firefox 中，網頁內的 JavaScript 跑起來說不定會跟飛的一樣。
&lt;br/&gt;
&lt;br/&gt;
若是真有人拿 AVM 來寫伺服器，說不定會光復 JavaScript 在 Server 端的失土哦 (好吧! 天方夜譚)! 說真的，AVM Server 版若成(例如成為 Apache 的一個 module)，要威脅 Java 或 .NET 既有地位是比較困難，因為這兩個平台既有應用多、進化動力也強；但對其他 Server 端的 Scripting Language 絕對是個威脅。想想看，若你能在 Server 端及 Client 端同時使用 ECMAScript，那使用 Ruby 或 PHP 的誘因是否會漸漸變弱呢！而 Ruby 會紅，並不是語言本身之美所致，而是出了一個 Ruby on Rails Framework，而 framework 裡面的 concepts 是很容易 porting 到別的語言或平台中的。
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight: bold;"&gt;其他：&lt;/span&gt;
&lt;br/&gt;
&lt;br/&gt;
看了以上個人挑選出來的清單，看啊看的，現在還是程序導向和物件導向語言的天下。難道沒有其他不一樣思考面向的東西嗎? 有的，而且我們也還滿常用，像是 SQL，或是各式 Markup Language 了(雖然不是程式語言)。還有那些用在工程、模擬、統計分析、人工智慧上的，你沒有那個環境或從事相關職業，是幾乎無從著手的語言，而這些當然就不算在推薦之內。
&lt;br/&gt;
&lt;br/&gt;
&lt;span style="font-weight: bold;"&gt;結語：&lt;/span&gt;
&lt;br/&gt;
&lt;br/&gt;
一項語言要被廣為接受，在過去，我一直以為大廠的支援是個必要因素，但 PHP(XOOPs, Nuke...) 及 Ruby(RoR) 這種透過 Community 及 Killer Application 來帶動風潮的成功案例，似乎也印證了 "世界是平的" 的論點，在這個網路世代，不只大企業，小企業及個人一樣有機會。Killer Apps 與 Success Stories，可能比大廠背書更有價值。
&lt;br/&gt;
&lt;br/&gt;
而對於你的選擇，我想，如果要做個尋常的程式開發人員，我會建議你 ECMAScript Family 一定要學，那 Java 或 .NET 再選一種。若你是個不尋常 (開發特殊應用的軟體) 的程式設計師，通常也就沒什麼好選了，因為應用的型式就決定了我們的選擇。&lt;/p&gt;
&lt;p&gt;
          &lt;br/&gt;
        &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-2993449218720312221?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/2993449218720312221/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=2993449218720312221' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2993449218720312221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/2993449218720312221'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/12/2008.html' title='該學那些程式語言2008版'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-8139742009306871476</id><published>2007-11-14T14:48:00.001+08:00</published><updated>2007-11-14T14:48:50.754+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thought'/><category scheme='http://www.blogger.com/atom/ns#' term='diary'/><title type='text'>想起一段令人感傷的住事</title><content type='html'>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;記得在國小一年級時，班上有個年約 16 歲的同學。這麼大的年紀才唸小學，在以前經濟尚不發達的年代並不算特別。然而，他倒不是因經濟問題才延遲就學，而是因為學習上的理解力不佳。他可能可以勉強知道 1 + 1 = 2，但問他 3 + 4 等於多少，就已經超越他的能力了。事實上，他已唸了好幾次小學一年級了。 &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;由於年紀的及學習能力的因素，他常成為學校同學的笑柄。年代久遠，我已不記得我是要別的同學別取笑他，還是跟著別的同學一起欺負他。這樣從開學後一直過了一兩個月，突然有一個星期一他沒到學校。我想起，上個星期六放學時我似乎是跟他一起走路回家的，有一種不好的念頭出現在我的腦子中。 &lt;/p&gt;  &lt;p&gt;放學後，我到了那個我之前常去的小公園，我知道他家就在附近。我想問問他家人他去哪裡了，怎麼沒上學。還沒到他家，卻看到，他已經掛在相思樹上，上吊死了&amp;#x2026; &lt;/p&gt;  &lt;p&gt;我有另一個同學，他的哥哥因為高燒而智力受損，也就是一般認定的白痴。那種言語不清，看起來髒髒的，好像一段日子沒洗澡的樣子，大家都認得出來這樣的人。從他智力受損後，別人當然也會取笑他，大人小孩都欺負他，但他似乎不能區別那是不是欺負，他一直過得很快樂，真的是笑罵由人，從小到現在，快 40 歲了! &lt;/p&gt;  &lt;p&gt;這段年代久遠的記憶，多年來不曾在出現在我的腦海中。我甚至可能是選擇去故意遺忘它--我沒再去過那個鄉下的小公園。在那之後，的成長過程中，我也的確一直沒想起這事。讓我想起這事的原因，可能是因為某些情境觸發了我。我偶爾會聽到有人在教育小朋友時，說出：「你怎麼可以笨成這樣&amp;#x2026; 你為什麼不去死一死好了&amp;#x2026;」。 &lt;/p&gt;  &lt;p&gt;這段回憶提醒我，惡語傷人六月寒。即使是身邊的家人、朋友，也可能因一句不小心的剌激而走上絕路。而萬一傷人的話語成真，背負著的，可是一輩子的歉咎與不捨。&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-8139742009306871476?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/8139742009306871476/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=8139742009306871476' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8139742009306871476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8139742009306871476'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/11/blog-post.html' title='想起一段令人感傷的住事'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-1520667161321405616</id><published>2007-09-11T03:40:00.000+08:00</published><updated>2008-04-18T19:14:02.006+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thought'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>iGoogle 與 Google Reader 裡的 RSS 訂閱</title><content type='html'>&lt;p&gt;之前看到有人在「訐譙(ㄐ｜ㄝˊ ㄑ｜ㄠˊ)」&lt;a href="http://blog.xdite.net/?p=438"&gt;Google 把預設的 RSS 訂閱導到 iGoogle&lt;/a&gt; 去，有人說是版本有差，有人說是已改了回來。我的 firefox 則是到現在還是這個樣：只會導到 iGoogle 去。
&lt;br/&gt;
&lt;br/&gt;
雖然我也是 iGoogle 的愛用者，但是想放到 Google Reader 裡去細細品嚐的資訊，真的跟想放在 iGoogle 上的資訊不太一樣。強迫用戶只能接受 Google 的指定，未必合理。不過若是做個瀨尿牛丸，真正的把 iGoogle 跟 Google Reader 訂閱做進一步整合，也是可能的解法。
&lt;br/&gt;
&lt;br/&gt;
我的想法是，既然放在 iGoogle 上的 google bookmark 會在 google bookmark manager 內被自動置入 homepage folder，那何不如法泡製，將加入 iGoogle 個人化首頁的 feed，也自動放在 Google Reader 內的 homepage folder 中。如果用戶已在 iGoogle 內加入分頁標籤，那更可用頁籤名稱作為 Google Reader 內的 folder 名稱。
&lt;br/&gt;
&lt;br/&gt;
另外，在 iGoogle 內閱讀 RSS 文章時，如果也可以選擇將文章開啟在 Google Reader 中，那種感覺也是挺不賴的!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-1520667161321405616?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/1520667161321405616/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=1520667161321405616' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1520667161321405616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/1520667161321405616'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/09/igoogle-google-reader-rss.html' title='iGoogle 與 Google Reader 裡的 RSS 訂閱'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-6947060723247228685</id><published>2007-08-25T18:02:00.000+08:00</published><updated>2007-08-25T18:11:32.221+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mood'/><category scheme='http://www.blogger.com/atom/ns#' term='lifehack'/><category scheme='http://www.blogger.com/atom/ns#' term='diary'/><title type='text'>「留著」哲學</title><content type='html'>以前對於留在身邊的東西，總有一種去蕪存菁的怪癖。

我不喜歡沒有用的東西，我不喜歡用不到的東西。

凡是東西用不到了，總是想要將它移除，丟掉。
留著沒有用的東西，就是浪費空間。

而這年頭，會跟我們有所牽扯的東西，卻又不可勝數。

在網路上寫日誌、評論，會留下你在各地的思想點滴。
換了一家公司上班，就多了至少一份經歷，也至少多了一個銀行戶頭。

有些東西做了之後是無法拭去的，像是學歷，工作。
有些東西卻是可以加以刪除，像是那些因為換了工作後，久久未曾再動用的戶頭。

前一陣子心血來潮，想要將那些久未動用的戶頭清一清。
但其實對一個上班族而言，這麼簡單的動作卻未必容易。

大抵上，銀行會跟你說：抱歉哦！要到原開戶行才可以結清。
你還記得開戶行在哪嗎？
就算記得，你確定結清所得的款項會大於花了時間跟金錢跑到那兒的代價嗎？
更重要的是，說不定下次因為某些因素，可能還要重新啟用那銀行的戶頭呢！

所以我想：留著吧，也許以後會用得著。
當下，我只要先把那些零頭，轉到別的戶頭去就行了。
等到有一天我退休了，在畢業之前那段美麗的、短暫的、悠閒的時光中，
再來結清吧。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-6947060723247228685?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/6947060723247228685/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=6947060723247228685' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/6947060723247228685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/6947060723247228685'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/08/blog-post_1983.html' title='「留著」哲學'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-7569746657238681395</id><published>2007-08-25T17:58:00.000+08:00</published><updated>2008-04-18T19:19:15.205+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='creative'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='mindhack'/><title type='text'>奇妙有趣的設計塔圖</title><content type='html'>&lt;p&gt;「設計塔圖」是一種神奇的「創造性思考技法」，依照「設計塔圖」思考技巧所建構出來的思想產物，將同時具有連續性與關連性。如果將任一處的連接線切斷的話，那麼整個系統就將遭到破壞。「設計塔圖」對於聯想力及系統化思考，極為有益。
&lt;br/&gt;
&lt;br/&gt;
我們以「何謂備忘錄」這個主題，來說明「設計塔圖」的應用方式。
&lt;br/&gt;
&lt;br/&gt;
備忘錄具有聯想、資訊、留言三種功能，因此就把這些功能當成三角形的頂點記下，到此已完成基本骨架。
&lt;br/&gt;
&lt;br/&gt;
然而，為了使備忘錄促進聯想，就必須把所想到的事項立刻記下來。也就是說，書寫工具必須和備忘用紙同時攜帶在身上。於是在「聯想」之下，就立刻出現「攜帶」這個字眼。
&lt;br/&gt;
&lt;br/&gt;
其次，必須要能妥善的「保存」備忘錄，才能使它的「資訊」架值得以彰顯，但若要使資訊更有價值，更有助於聯想，就得好好「整理」備忘內容。
&lt;br/&gt;
&lt;br/&gt;
就另一項功能「留言」而言，它與其他兩項功能最大的差異在，它必須不斷的意識到「他人」的存在。這不是為自己而作的備忘錄，而是為他人而做的。在備忘錄的內容被接收之後，這份備忘錄也就可以「消滅」了。
&lt;br/&gt;
&lt;br/&gt;
而就交付者的立場來說，要儘量網羅5W2H的內容。如此一來，就算備忘錄離開自己的手上，內容也不會遭到誤解。
&lt;br/&gt;
&lt;br/&gt;
另一方面，就接收留言者的立場來說，也可妥善應用備忘錄，將其內容「內在化」，加以了解及吸收，以提昇自己的構想。
&lt;br/&gt;
&lt;br/&gt;
與備忘錄有關的「設計塔圖」完成了。普通的發想法通常只是針對特定的主題作各種聯想，因此常呈片段而零亂的狀況。 而「設計塔圖」，卻能將這些零亂的聯想系統化。
&lt;br/&gt;
&lt;br/&gt;
有了這一張圖，不但可顯示要點，亦能將之擴大成文章，一魚多吃。但在過程中，卻好像只是進行了一場排列關鍵字的遊戲而已。
&lt;br/&gt;
&lt;br/&gt;
※ 給採用 RSS 閱讀軟體的讀者：有些 RSS 閱讀軟體並不能正常顯示內嵌物件，請移駕本文原始網頁，才能看到 slide show 講解的「設計塔圖」。謝謝!!
&lt;br/&gt;
&lt;br/&gt;
&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="450" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" height="500"&gt;
            &lt;br/&gt;
&lt;param name="movie" value="http://static.scribd.com/FlashPaperS3.swf?guid=a315e1ar0qjxk&amp;amp;document_id=258628"/&gt;
 &lt;param name="quality" value="high"/&gt;
 &lt;param name="menu" value="false"/&gt;
 &lt;param name="wmode" value=""/&gt;
 &lt;embed src="http://static.scribd.com/FlashPaperS3.swf?guid=a315e1ar0qjxk&amp;amp;document_id=258628" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="" quality="high" menu="false" height="500" width="450" type="application/x-shockwave-flash"/&gt;
          &lt;/object&gt;
        &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-7569746657238681395?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/7569746657238681395/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=7569746657238681395' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/7569746657238681395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/7569746657238681395'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/08/blog-post_9777.html' title='奇妙有趣的設計塔圖'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-5449869286355456479</id><published>2007-08-01T18:57:00.000+08:00</published><updated>2007-08-27T19:00:02.653+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='managment'/><category scheme='http://www.blogger.com/atom/ns#' term='essay'/><title type='text'>管理寓言：男人愛當顧問</title><content type='html'>&lt;p&gt;在彭懷真所著的《時間好經營》中，讀到這樣一個管理寓言：
&lt;/p&gt;&lt;blockquote&gt; &lt;p&gt;甲君養了隻愛叫春的公貓，每晚嚎叫吵得鄰人無法入睡。在群情激憤下，甲君不得已將公貓送去獸醫處使其不能貓道。幾天過後鄰人仍見那公貓夜夜外出  “辦事”。鄰人不解而問之，甲君便說：牠現在到處去給別人當顧問。 &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;自從聽到這個比喻之後，我就對顧問這個身份感到過敏 (偏偏我的 title  便是顧問)。從上面的故事來看，似乎在諷刺顧問是只剩一張嘴，不能幹正事的人。不過，我在大陸的&lt;a href="http://blog.china.alibaba.com/blog/wsggood1234/article/b0-i2188480.html"&gt;網站&lt;/a&gt;上看到另一個版本，而有不同的解釋： &lt;/p&gt;&lt;blockquote&gt;社區裏，有只公貓，花心，夜夜出去，找母貓鬼混。
後招各家公貓投訴，女主人一狠心，把這只花心貓喀嚓了。
花心貓被喀嚓了後，仍然夜夜出去，回來後竟然更得意。女主人大奇。
花心貓得意地說：“您把我喀嚓之後，我是不行啦，那些公貓也安靜了幾天，不過他們現在都高價請我去做consultant。”
&lt;/blockquote&gt; &lt;p&gt;該站作者解說如下：
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;各家公貓投訴，說明這只貓很有魅力和能力。暗喻在公司裏面能力非常強的sales，但是這個sales很自狂，未處理好同事之間的利益關係，遭同事到老闆那裏投訴。 &lt;/li&gt;&lt;li&gt;女主人把這只貓喀嚓了。暗喻老闆是昏君，賢能招妒無善終。 &lt;/li&gt;&lt;li&gt;公貓後來被大家聘consultant.暗喻公貓的實戰能力還是大家公認的，做consultant是無奈之舉。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;不過我覺得這樣的解釋也有些牽強。有實力的人，何以只能無奈的做consultant。真正有實力的話，不但能在旁指導，甚且可以自己入場打場好球。有道是心寬天地寬，何必自嘲受昏君閹割啊！&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-5449869286355456479?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/5449869286355456479/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=5449869286355456479' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/5449869286355456479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/5449869286355456479'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/08/blog-post_27.html' title='管理寓言：男人愛當顧問'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8793914344847646557.post-8404100215530184859</id><published>2007-07-26T02:44:00.000+08:00</published><updated>2007-09-11T02:56:46.758+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diary'/><category scheme='http://www.blogger.com/atom/ns#' term='reading'/><title type='text'>台北市圖書館的貼心服務</title><content type='html'>大家都知道圖書館可以借書，但若談到預約借書的功能，可能就比較少人知道或使用了。而把預約借書功能發揮到極致的，我想台北市立圖書館算是其中的佼佼者。

預約書籍很簡單，首先，你要辦妥借書證。然後登入&lt;a href="http://www.tpml.edu.tw/TaipeiPublicLibrary/"&gt;台北市立圖書館網站 &lt;/a&gt;(密 碼預設是你的生日)，搜尋感興趣的書籍。找到書籍後，便可按下畫面上的預約連結進行預約。也許有些書籍只在其他館藏中才找的到，沒關係，台北市圖書館讓你 可以跨館預借，並讓你自由指定所要取書的分館。大概一段時間後 (約一個禮拜)，圖書館會幫你把書備妥，送到指定的分館，並發出 email 跟電話通知你在三天內取書--完全不收分文。email 格式長相像下面這樣：
&lt;blockquote&gt;          MR. XXX

臺端所預約之以下圖書已到館,請至圖書館辦理借閱,
收到本館通知逾3日未取則（送回原典藏館）上架供其他讀者
閱, 謝謝 !
請注意︰此郵件是系統自動傳送，請勿直接回覆此郵件，若
需要請直接與(取書館)聯絡。
1   XXXXX/ AAAA ; BBB, CCC譯
    AAAA
    call number:000.0 0000                                  copy:1

2   YYYY: YYYYYYY/ DDDD. EEEEE著 ; FFF譯
    DDDD
    call number:111.1 1111                                  copy:1
&lt;/blockquote&gt;如果你想，甚至可以要求圖書館將書透過貨運送到你家，而你只要出資支付貨運費即可。

Anyway，這是一項相當體貼便民的服務。不過我也擔心，若是使用這服務的人多了起來，是不是會造成圖書館的作業成本太高…考慮到這點，還是把借回來的書努力的 K 完再說吧。

※ 2007/9/1 另一點通知：台北市圖書館用悠遊卡也可以借書了喔! 詳情&lt;a href="http://www.tscc.com.tw/news.php?id=150"&gt;見此&lt;/a&gt;。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8793914344847646557-8404100215530184859?l=isong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://isong.blogspot.com/feeds/8404100215530184859/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8793914344847646557&amp;postID=8404100215530184859' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8404100215530184859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8793914344847646557/posts/default/8404100215530184859'/><link rel='alternate' type='text/html' href='http://isong.blogspot.com/2007/07/email-email-mr.html' title='台北市圖書館的貼心服務'/><author><name>Edward</name><uri>http://www.blogger.com/profile/13637533567636695411</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
