TypeScript 學習筆記(6) – Classes

主要看這篇:Classes

大致用法跟 C#/Java 差不多,幾個特別的地方:

  1. readonly :成員可以加上 readonly 來修飾,表示是唯讀。
  2. 有 getter/setter:可以用 get/set 這兩組 accessor 讓 method 變成屬性。
    class Employee {
        private _fullName: string;
    
        get fullName(): string {
            return this._fullName;
        }
    
        set fullName(newName: string) {
            this._fullName = newName;
        }
    }
    
  3. static:類似 java/c# 那樣的用法,原本 javascript 是沒有的。
  4. abstract 修飾:可以加在 class 前面,也可以加在 method 前面,用法跟 java/C# 相似。

後面提到的 constructor functions 是一個進階技巧,不過感覺上用到機會不大。

TypeScript 學習筆記(5) – Interface

今天是看這篇:Interfaces

TypeScript 有 anonymous interface ,就像下面的程式一樣:

// 有點 anonymous interface 的味道
function printLabel1(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

// 也可以明確的用 interface 寫
interface LabelledValue {
    label: string;
}

function printLabel2(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

 

在宣告成員時,如果加入 ? ,表示可有可無,這個寫法應該是參考了 Ruby 的作法

interface SquareConfig {
    color?: string;
    width?: number;
}

 

用 readonly 修飾詞則是表示唯讀

interface Point {
    readonly x: number;
    readonly y: number;
}

 

如果要需告一個唯讀的陣列,可以用 ReadonlyArray

let ro: ReadonlyArray = a;

 

我覺得 Function types 比較不是那麼直覺,不容易看懂

interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    let result = source.search(subString);
    return result > -1;
}

大抵來說就是 python 的 __call__ 或是 c++ 的 operator()。

Indexable type 也是不太直覺

interface StringArray {
    [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

大抵來說就是 python 的 __item__ 或是 c++ 的 operator[]。

要讓類別實作介面是用 implements 關鍵字

interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

 

下面這例子是想要限定 ClockInterface 裡的 constructor 必須符合 ClockConstructor 規範的作法,第一眼不太容易看懂。

interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

// 傳進來的 ctor 必須符合 ClockConstructor 的規範,要有 hour 跟 minute 這兩個 number 型別的參數。
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

 

介面也可以繼承,跟類別一樣,是用 extends,而且允許繼承多個

interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}

 

蠻令我驚訝的是,Interface 可以繼承 class … @_@

TypeScript 學習筆記(4) – 變數

JavaScript 提出了兩個新的關鍵字:let 與 const。使用 let 可以避免使用 var 的一些奇妙現象;而 const 就是跟 C 的 const 一樣,避免再次指定值給這個變數。

Variable Declarations 裡提了許多 JavaScript 使用 var 宣告變數時的奇妙現象,然後解說為什麼要改用 let。這部份我偷懶跳過去了,我的想法是,就都改用 let 吧。

另外有提到 Destructuring,就是類似 Python 的 unpack :

// JavaScript/TypeScript
let input = [1, 2];
let [first, second] = input;

Python 則是:

# Python
first, second = (1, 2)

也跟 Python 3 一樣,有取 remain items 的效果:

let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // outputs 1
console.log(rest); // outputs [ 2, 3, 4 ]

Object destructuring 是個比較特別的東西,意思跟 destructuring 差不多,但對象是 object,也就是可以將 object 的某幾個屬性放到變數裡。

let o = {
    a: "foo",
    b: 12,
    c: "bar"
}
let { a, b } = o;
({ a, b } = { a: "baz", b: 101 });  // 這樣也可

也支援 remaining items 的方法:

let { a, ...passthrough } = o;

Object destructuring 還支援 default values,意思是如果 wholeObject 沒有 b 屬性時,就把 b 指定為 1001:

function keepWholeObject(wholeObject: { a: string, b?: number }) {
    let { a, b = 1001 } = wholeObject;
}

也可以應用到 function 上,我覺得這個例子比較清楚,可以應用在只取物件的某幾個屬性來使用時:

function f({ a, b } = { a: "", b: 0 }): void {
    // ...
}
f(); // ok, default to { a: "", b: 0 }

Spread 算是陣列相加的一個 syntax sugar,可以把 first, second 塞到 bothPlus 這陣列裡去:

let first = [1, 2];
let second = [3, 4];
let bothPlus = [0, ...first, ...second, 5];

也可以應用在 object 上,目前想到可以用來做 object proxy 或是 composite 之類的,不過不適合也不一定。

let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { food: "rich", ...defaults };

 

TypeScript 學習筆記(3) – 基本型別

今天是看這篇:Basic Types

裏面直接建議用 ES6 的 let 替代 var 了。

  • boolean:布林型態
  • number:數字型態,沒有 integer, long, float, double 之類的,只有 number,JavaScript 裡的數字都是 float。
  • string:字串
  • array:陣列,在型別後面加上 [],例如: let list: number[] = [1, 2, 3]; ,要注意的是,無法指定固定個數。
  • tuple:就 tuple ,有點像陣列,但能指定每個元素的型態,這跟 Python 不一樣。例如:
    let x: [string, number];
    let x = ["Hello", 100];
    let y: [string, number] = ["John", 200];
    y[2] = "Doe";
    console.log(y);  // 輸出 [ 'John', 200, 'Doe' ]
    
  • enum:列舉,用法跟其他語言大致相似:
    enum Color {Red, Green, Blue};
    let c: Color = Color.Green;
    // 比較特別的用法
    let colorName: string = Color[2];
    console.log(colorName);  // 輸出 Blue
    
  • any:任意型態,但要注意的是跟其他語言所指的 Object 型別不同,TypeScript 有獨立一個 Object 型別。說起來跟 C# 的 dynamic 比較相似。
    let notSure: any = 4;
    notSure.ifItExists(); // 通過編譯,因為可能在執行時期就有 ifItExists()
    notSure.toFixed(); // 通過編譯,因為可能在執行時期就有 toFixed()
    
    let prettySure: Object = 4;
    prettySure.toFixed(); // 編譯錯誤,編譯時會有 Object 型別沒有 toFixed 的錯誤。
  • void:就 void ,表示不會傳回任何東西
  • null:就 null ,可以把任何型態的變數指定為 null
  • undefined:就 undefined,可以把任何型別的變數指定為 undefined
  • never:表示絕對不會傳回變數,
    // 只會丟出例外
    function error(message: string): never {
        throw new Error(message);
    }
    // 裏面是不會結束的迴圈
    function infiniteLoop(): never {
        while (true) {
        }
    }

Type assertion ,有 C/C# 強制轉型的意味。

let someValue: any = "this is a string";
let strLength: number = (someValue).length;
// 也可以用類似 c# as 的語法
let strLength: number2 = (someValue as string).length;

 

TypeScript 學習筆記(2) – Type annotation/Interface/Class

以下是看 Quick start 的紀錄:

  • Type annotation:一般動態語言是沒型別的,但 TypeScript 加上了這部份的支援,這可以讓開發者在編譯時期就預先發現型別錯誤,也可以編譯出更有效率的程式,讓程式執行的更快。語法像是 Go 或 Pascal (知道這語言的人應該不多了),是在變數後面加上 :type,例如:
    var str:string="hello world";
  • Interface:介面,沒啥特別的,看範例比較快
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    function greeter(person: Person) {
        return "Hello, " + person.firstName + " " + person.lastName;
    }
    
    var user = { firstName: "Jane", lastName: "User" };
    
  • Class:大致上跟 java 的用法相似,不過在看到 QuickStart 範例時,還是驚訝了一下,主要是因為 TypeScript 語法並沒有明確指定類別實作了 Person 介面,但這個類別所產生的物件仍可以直接丟到只接介面的函式裡。後來仔細看了一下,才知道是因為 TypeScript 的 constructor (建構子)裡的參數加了 public,那麼會自動將這個參數放到同名的屬性去,也因此就符合了 Person 介面的要求。
    class Student {
        fullName: string;
        // 這裡的 public firstName,等同是函式裡有 this.firstName=firstName
        constructor(public firstName, public middleInitial, public lastName) {
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
    }
    
    // 故意不要有 lastName
    class Employee {
        constructor(public firstName) {
        }
    }
    
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    // 因為 Student 裡有 firstName, lastName 屬性,視同實作了 Person
    function greeter(person : Person) {
        return "Hello, " + person.firstName + " " + person.lastName;
    }
    
    var user = new Student("Jane", "M.", "User");
    var employee = new Employee("John");
    console.log(greeter(user));
    // console.log(greeter(employee));  // 加了這行,編譯會發生錯誤,告知 employee 不符合 Person 介面
    

TypeScript 學習筆記(1) – 安裝與執行

我習慣用的環境是 Ubuntu,目前用的是 16.04 Xenial。

第一步是安裝,安裝 nodejs 有幾種方法:

  1. nodejs.org 下載 tarball,手動安裝。
  2. 用 debian package 來安裝 (nodesource)
  3. 用 nvm 來安裝

之前有用過 nvm 了,這次我選擇用 debian package 來安裝 LTS 版的 nodejs。

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs

安裝好,就可以利用 npm 來安裝 TypeScript 了。不過,因為我不想把 typescript 安裝在系統路徑 (一般是用 sudo npm install -g typescript),所以我多設定了 .npmrc 以及環境變數

prefix = /home/user/.local
root = /home/user/.local/lib/node_modules
binroot = /home/user/.local/bin
manroot = /home/user/.local/share/man

 

export LOCAL_PATH="$HOME/.local"
export MANPATH="$LOCAL_PATH/share/man:$MANPATH"
export NODE_PATH="$LOCAL_PATH/lib/node_modules:$NODE_PATH"
export PATH="$LOCAL_PATH/bin:$PATH"

 

在設定好以後,使用 npm install -g 時,會將這些套件安裝到自己的 $HOME/.local 目錄下。

在使用 npm install -g typescript 以後,我另外安裝了去年推出的 yarn。

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt install yarn

 

首先寫一個 hello.ts

console.log("Hello world.");

然後用 tsc 來將 hello.ts 編譯為 hello.js: tsc hello.ts ,最後就可以用 node 執行 hello.js 印出 “Hello world.”

電影流水帳(2017/1/1~2017/1/11)

有村架純 #jdgmovie #jdgacter 有村架純

  • 寒戰2 (IMDB, Wikipedia)。整體來說,我覺得比前集稍弱了些。
    延續上集的發展,李文彬兒子李家俊入獄,但幕後的黑手蔡元祺以劉傑輝的家人作為人質跟劉傑輝談判、斡旋,劉傑輝不得已,只能隻身押解李家俊去指定的地點,但透過同黨的幫忙,李家俊逃走,劉傑輝因此面對調查會與輿論的壓力。
    蔡元祺這時出面拉攏李文彬,說明香港政治高層的佈局計劃,要求他一起加入這行動。於是就開始利用之前的衝鋒車與調查會來鬥爭劉傑輝。調查會裡的簡奧偉覺得事情不單純,派自己好友的女兒歐詠恩去調查。而劉傑輝也不甘示弱,結合了廉政署展開警政體制外的祕密調查行動。後來歐詠恩因為調查行動而被蔡元祺人馬害死,於是簡奧偉跟劉傑輝聯手,找出蔡元祺一行人窩藏衝鋒車的地方,並展開反擊。最後,劉傑輝與蔡元祺達成協議,蔡元祺遠走國外,劉傑輝穩住自己的位置以及香港高層的穩定,李文彬則被強制退休。從最後的故事走向,似乎是會有第三集的樣子。
  • ビリギャル (IMDB, Wikipedia),台譯:墊底辣妹。之前有買書,所以特別把電影也看過一次。我覺得改編的不錯,保留了書裡的故事性,把書裡大部份教怎麼唸書的地方抽離,卻又不失味道,相當勵志的故事。
    さやか是個沒怎麼唸書的少女,在母親的支持之下,到了青田塾。青田塾的坪田老師是個特別的老師,以一對一的對談去了解並引導學生, さやか因此慢慢開始轉變,並且開始對唸書有了興趣,也對自己有了信心。
    最後,在 さやか的努力下,家裡的氣氛改變了,自己的成績也愈來愈好,順利考上了慶應大學。
  • 盜墓筆記 (IMDB, Wikipedia)。前面的劇情還可以,到了後面就走味了,而且是濃濃的腐味。
    一開始是帶出悶油瓶跟外國人反派的過節,接著鋪陳出吳邪的身世以及銅片與蛇母的祕密。經過一番交代,三叔就帶著吳邪、悶油瓶跟潘子下墓探險了。值此同時,外國人反派也派了阿寧(馬思純)帶著一群傭兵去伺機搶奪。在蛇母墓展開一場你追我奪的探險,到了最後,蛇母出現,從這邊開始,莫名其妙的帶出阿寧跟胖子(阿寧隊上的翻譯)的愛情線,悶油瓶跟吳邪的腐味。與蛇母的大戰並不順利,吳邪天真的要求外國人反派幫忙,而反派居然答應了,於是順利的逆轉局勢,消滅蛇母。三叔、吳邪跟阿寧等主角順利的逃出,悶油瓶則犧牲了,看起來是還有續集的樣子?
  • 瘋狂的賽車 (IMDB, Wikipedia)。好幾年前看過一次,這次是重看的。話說啊,維基百科裡的劇情真的寫的超清楚的。
    耿浩在一次比賽後被設計了,導致拿到的銀牌飛了,也被禁賽。他的師傅氣到中風,耿浩只能開著貨車幫人送貨過活。後來師傅在電視上看到害他們的李法拉,再次氣到從樓上滾下去,死了。耿浩為了安葬師傅,決定找李法拉討錢。
    李法拉則是想把妻子殺了,所以找了殺手二人組來動手,結果反被妻子收買,改為去修理李法拉。後來陰錯陽差的變成李法拉親手殺了自己的妻子。從台灣來的烏龍幫四人組,來中國做毒品交易,結果一直沒能做成交易。故事就在這些人裡轉來轉去,產生出一連串的巧合,到了最後,李法拉跟烏龍幫四人組死了,殺手二人組成了証人,耿浩報了仇,拿到了錢,為師傅風光大葬。

groovy 的編譯

用 Gradle 做很方便,build.gradle 裡要加

apply plugin: 'groovy'

然後程式碼依照 The Groovy Plugin – Gradle User Guide Version 3.2.1 裡的說明來安排就可以:

目錄 放什麼
src/main/java Java 程式碼 (對,可以跟 Java 一起編譯)
src/main/resources 會用到的資源
src/main/groovy Groovy 程式碼,也可以放 Java 程式碼
src/test/java Java 測試案例
src/test/resources 測試案例會用到的資源
src/test/groovy Groovy 測試案例
src/sourceSet/java Java source for the given source set
src/sourceSet/resources Resources for the given source set
src/sourceSet/groovy Groovy sources for the given source set. May also contain Java sources for joint compilation.

然後執行 gradle build 進行編譯,接著就可以在 build 裡找到 jar 檔案。

但是要注意的是,這個 jar 檔案不是 executable jar 檔案 (用 java -jar 就可執行的 jar ),要編譯為 executable jar 檔,得多做一些工。

第一個是要在 build.gradle 裡指定 manifest ,也就是在製作 jar 時,指定 META-INF ,告訴 java -jar 說,該執行哪個類別裡的 main。像下面就是自訂 Jar task ,並指定 manifest 的程式。

task uberjar(type: Jar) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': 'Program'  // 這邊就是依照 groovy 的類別與程式來放,假設下面的 groovy 程式放在 src/main/groovy/program.groovy
    }
}

接著,在 groovy 的主程式裡,加入 main ,這個 main 其實跟 java 的規定一樣,必須是 public, static ,接受字串陣列。


class Program {
  public static void main(String[] args){
    println "Hello world"
  }
}

最後執行 gradle uberjar ,就可以得到 executable jar 了
參考資料:

電影流水帳(2016/12/9~2016/12/31)

Amy Adams in St Helier, Jersey
Amy Adams ,重看神鬼交鋒時,赫然發現她也有演出,哈!

  • Catch me if you can (IMDB, Wikipedia),台譯:神鬼交鋒。這部電影在第四台看過好多次了,但都是片斷的看,這次終於願意在 Netflix 上從頭到尾看完一次,相當好看的一部電影。
    Frank 因為父母的離異而離家出走,靠著自己的聰明才智冒充機長、醫生來開假支票,騙取生活費用。假支票開多了,被 FBI 的 Carl 盯上了,於是開始你追我逃的日子。後來 Frank 在醫院認識了 Brenda ,本想跟著 Brenda 的父親當個律師從此平淡過生活,可是 Carl 緊追在後,Frank 只好拋下 Brenda 逃到法國去。Carl 也跟著追到法國,並且逮到 Frank,將他引渡回美國坐牢。
    Carl 因為之前的追捕過程對 Frank 也算是有感情,就去探監,Frank 無意指點了 Carl 關於假支票的線索。Carl 後來就找了長官,把 Frank 借出來幫忙辦案,後來成為知名的金融犯罪專家。
  • Saving Private Ryan (IMDB, Wikipedia),台譯:搶救雷恩大兵。還不錯的電影,戰爭場面蠻寫實的。讓我比較驚訝的是看到玩命光頭的 Vin Diesel 也有在這部電影裡演出。
    美國軍方意外發現三個 Ryan 都出自同一個家庭,為了避免四兄弟都死去,查到最後一個 Ryan 在歐洲戰線,於是派出小組去救援。這個小組突破德軍防線找到 Ryan 後,Ryan 卻不肯離去,於是小組只好協助 Ryan 所屬的部隊防守。這場防衛戰打的很辛苦,就在敗退到最後防線,要炸掉橋的時候,盟軍的部隊趕到,讓 Ryan 免於死去。但是來救援 Ryan 的小組幾乎死傷殆盡,Tom Hanks 飾演的 Miller 也受了重傷,臨終前,要 Ryan 好好的把他們這些人的份活下去。
    經過數十年,老去的 Ryan 趕到 Miller 的墓前淚流滿面,要自己的妻子告訴自己有好好的活這些年,自己有做個好人。

仔細想想,今年好像看了不少 Tom Hanks 演的電影:航站情緣、阿甘正傳(年初的時候陪小姨子重看的)、神鬼交鋒跟搶救雷恩大兵。上篇算到 73 ,加上這篇看的兩部電影就 75 啦~

電影流水帳(2016/10/28~2016/12/8)

搞不好這是今年最後一篇也說不定,今年有個忙碌的年底。今年總共看了 73 部電影,也看了「重版出來」、「House M.D.」、「Sherlock」、「IT 狂人」等等的影集,跟往年相比,多看了 13 部電影,不過有不少部電影都是因為之前沒紀錄到而乾脆重看的。

Kristen Stewart (Bella Swan) 我覺得 Kristen Stewart 是個星運相當不錯的人,印象中最早看到她的電影是跟 Jodie Foster 合演的 Panic room,然後之後的幾年演了鼎鼎大名的木瓜之城暮光之城系列電影,今年也跟李安合作了 Billy Lynn’s Long Halftime Walk ,很難得有人能這麼順遂。當然,也是因為她本身的演戲實力堅強的原因絕對不是因為臭臉

  • Back to the future 2 (IMDB, Wikipedia),中譯:回到未來2。承接上集的結尾,Marty 回來後不久,博士急急忙忙的趕來找他,說未來他的兒子被抓去關了,要 Marty, Jennifer 跟他一起去未來。三人到了未來,誤打誤撞地救了 Marty 的兒子,可是卻也讓老 Biff 知道有時光機的存在。老 Biff 帶著運動年鑑回到更早的過去,改變了歷史,這導致博士跟 Marty, Jennifer 回到他們的時間點時,發現整個世界都跟原來的不一樣了。於是他們再次回到老 Biff 改變歷史的時間點,也就是第一集 Marty 回去的時間點,阻止了老 Biff。就在博士跟 Marty 要回去的時候,發生了意外,博士跟時光機被閃電打中,回到了更早的過去。這時候 Marty 在風雨中看到遠方來了一輛車,車上的人告訴他,有一封信是要留給你的。Marty 看了才知道,是回到過去的博士寫的信,同時信裡留下了線索。對,還有第三集。
  • American Ultra (IMDB, Wikipedia),中譯:廢柴特務。與其說是動作片,我覺得比較像是愛情片。還蠻有趣的故事,電影的安排也不錯,從頭到尾都沒冷場。
    Mike 是個魯蛇,有個在便利商店顧店的工作,平常沒事就是跟女友 Phoebe 窩在一起。始終想帶 Phoebe 出國走走,可是始終克服不了心裡的恐懼。CIA 內部展開了清洗計劃,想要將 Mike 給洗掉,但之前負責 Mike 計劃的 Victoria 不想浪費之前的成果,就趕到 Mike 那邊,以祕密的口令喚起了 Mike 的潛在能力。接著 Mike 的能力慢慢覺醒,並擊退了 CIA 派來殺掉他的特工。到後來 Mike 慢慢恢復記憶,也慢慢知道了事情的真相。原來 Phoebe 是 CIA 特工,在參與 Mike 計劃時,愛上了 Mike ,所以計劃結束的時候,決定跟 Mike 生活在一起,並暗中保護他。最後,Mike 消滅了所有派來殺他的特工,而 Victoria 則告了御狀,將發動清洗計劃的主管給免職。Mike 與 Phoebe 則繼續當特工,為 CIA 出任務。
  • Shaun of the Dead (IMDB, Wikipedia),中譯:活人甡吃。非常對我胃口的一部電影,裏面充滿相當多的惡趣味。
    Shaun 是個店領班,Ed 與他同住,Shaun 每次跟女友在一起,都會帶著 Ed。Liz 覺得這樣下去不行,發出最後通牒,希望能有兩人獨處的時間,Shuan 為了挽回這段感情,就訂了餐廳,打算來個浪漫的兩人約會。結果,在 Shuan 訂餐廳的這段時間,小鎮發生了大事,僵屍入侵。後來,Shuan 跟 Liz 分了,在 Ed 幫 Shuan 化解失戀苦悶的時候,兩人發現到小鎮不對勁了。於是兩人計劃好要先去救 Shuan 的媽媽,再去救 Liz ,然後逃到酒吧去。
    世事往往難料,Shuan 跟 Ed 兩人救出了 Shuan 的媽媽,卻沒能救到 Shuan 的繼父;救出了 Liz ,逃到酒吧,卻發現一行人陷入了被僵屍包圍的窘境。最後只剩下 Shuan 跟 Liz 逃出酒吧,逃出時,眼看就要被僵屍攻擊,這時候軍隊出現,救了他們。電影的最後,變成了人們與僵屍和平共處,Shuan 跟 Liz 圈養了變成僵屍的 Ed ,一起過著還不錯的生活。
  • The Transporter Refueled (IMDB, Wikipedia),中譯:玩命快遞4。前面有點精彩,後面弱掉,有點可惜。深深覺得男主角 Frank 的父親比 Frank 更有戲,更有值得去挖的故事。說真的,我蠻想知道 Frank 父親在退休前到底做了什麼事。
    Anna 被賣淫集團掌控,決心復仇,經過數年以後,找到了志同道合的同伴,展開復仇行動。她綁架了 Frank 的父親,請 Frank 幫忙復仇計劃。Frank 為了父親,該幫的忙都幫了,救出父親以後,就要離開。豈知,才剛把父親送回家,父親居然又被犯罪集團給綁走。犯罪集團首腦要求 Frank 將Anna 等人與帳本帶去海邊的遊艇找他,Frank 為了父親,只好再去找 Anna 商量,於是他們就一同去遊艇展開決戰。Anna  巧妙的利用集團內的矛盾,讓他們內訌,接著透過 Frank 的幫忙,進而取得優勢。最後,Anna  拿到犯罪集團的錢,將錢分給她死去的同伴,Frank 則繼續他的工作。
  • Wall-E (IMDB, Wikipedia),中譯:瓦力。前同事 M 推薦給我的作品,M 超喜歡的,不過我一直都沒機會看這部電影。
    Wall-E 是個機器人,孤單的在地球上作著回收處理的工作,某天,他發現了植物。沒多久,太空船降落在地球上,Eve 從船裡走出來,她到處探測著地球。Wall-E 愛上了這個具有流線外型的機器人,很努力的想跟她交朋友,可是 Eve 只顧著執行任務。後來,Eve 發現了 Wall-E 所發現的植物,任務完成,她自動關閉,等待回收。在等待回收的這段時間,Wall-E 試著救她,帶著她約會。
    分離的時刻到來,Eve 被太空船回收,Wall-E 以為是壞人,就跟著上去,想把她救回來。到了太空船的母船以後,才知道是流浪太空的地球人的基地。母船上的地球人基本上已經退化,所有的事情都由機器人包辦,母船上的機器人在得知 Eve 找到植物以後,根據之前收到的命令,阻止船長下達駛回地球的命令。但是在 Eve, Wall-E 與船長的努力之下,他們終於成功的讓母船回到地球。可是,Wall-E 損毀了,Eve 非常的難過,在母船回到地球以後,Eve 試著用 Wall-E 保存下來的零件去救 Wall-E ,經過一番努力,終於成功的救回 Wall-E 。
    這一段, Eve 看到 Wall-E 在地球如何照顧關機的 Eve 與試著拯救 Wall-E 的經過相當感人,我相信這也是前同事 M 喜歡 Wall-E 的原因吧。