GNU Smalltalk

GNU Smalltalk是Smalltalk程式語言的GNU計劃實現。這個實現不同於其他Smalltalk環境，使用文字檔案作為程式輸入，並將其內容解釋為Smalltalk程式碼。在這種方式下，GNU Smalltalk表現得更像是一種直譯器，而非傳統Smalltalk方式下的一種環境。GNU Smalltalk包括了對很多自由軟體庫的繫結，包括SQLite、libSDL、cairo、gettext和等。簡單例子.下面的例子可工作在GNU Smalltalk 3.0和以後版本上。經典的Hello, World!例子：'Hello, World!' displayNlGNU Smalltalk聲明瞭三個檔案：codice_1、codice_2和codice_3，作為檔案串流類的唯一例項，它通常將寫操作委託給codice_2。一些基本的Smalltalk程式碼："所有東西，包括一個文字，都是一個物件，所以如下可行:"-199 abs. "199"'gst is cool' size. "11"'Slick' indexOf: $c. "4"'Nice Day Isn"t It?' asLowercase asSet asSortedCollection asString "' "?acdeinsty'"兩個codice_15包圍的是註釋；codice_16是字元常量codice_17；兩個codice_18包圍的是字串，字串中的codice_15是codice_18的轉義序列。蒐集.構造和使用一個數組：a := #(1 'hi' 3.14e0 1 2 (4 5)).a at: 3. "3.14"a reverse. "((4 5) 2 1 3.14 'hi' 1)"a asSet "Set(1 'hi' 3.14 2 (4 5))"構造和使用一個散列表，它是雜湊蒐集類的例項：hash := Dictionary from: { 'water' -&gt; 'wet'. 'fire' -&gt; 'hot' }.hash at: 'fire' "'hot'".hash keysAndValuesDo:[ :k :v | ('%1 is %2' % { k. v }) displayNl ]."=&gt; fire is hot=&gt; water is wet""刪除 'water' -&gt; 'wet'"hash removeKey: 'water'GNU Smalltalk在字串類。這裡給它的蒐集，是在codice_31和codice_32之間包圍的，當前Smalltalk變體一般都提供的動態陣列，其中的元素可以在執行時間求值。塊和迭代器.引數傳遞到是為閉包的一個塊："remember被繫結到一個塊."remember := [ :name | ('Hello, %1!' % { name }) displayNl ]."時機成熟時 -- 呼叫這個閉包!"remember value: 'world'"=&gt; Hello, world!"從一個方法返回由兩個閉包構成的一個數組：Integer extend [asClosure [| value |value := self.].blocks := 10 asClosure.setter := blocks first.getter := blocks second.getter value. "10"setter value: 21. "21"getter value "21"這裡用codice_33為現存的類擴充套件新方法是GNU Smalltalk特有的語法。下面的考拉茲猜想例子，展示將兩個塊傳遞給接收者，並將結果資訊傳送回到呼叫者：Integer extend [ifEven: evenBlock ifOdd: oddBlock [^self evenifTrue: [ evenBlock value: self ]ifFalse: [ oddBlock value: self ]].10 ifEven: [ :n | n / 2 ] ifOdd: [ :n | n * 3 + 1 ] "5"蒐集類的codice_35方法，將接收者的每個元素傳遞給一個塊來求值，返回這些結果的蒐集。這類似於函數語言程式設計語言中map函式。例如計算從codice_36到codice_37的平方：(1 to: 10) collect: [ :x | x squared ] "(1 4 9 16 25 36 49 64 81 100 )"可迭代類定義了由子類實現的codice_39方法，將一個塊迭代於接收者的每個元素之上。這也被稱為隱式迭代器。例如迭代於陣列和區間之上：array := #(1 'hi' 3.14e0).array do: [ :item | item displayNl ]."=&gt; 1""=&gt; hi""=&gt; 3.14"(3 to: 6) do: [ :item | item displayNl ]"=&gt; 3""=&gt; 4""=&gt; 5""=&gt; 6"可迭代類的codice_40方法，接受一個引數和一個塊二者；它迭代於接收者的每個元素之上，在其上執行某個函式並保持結果為一個聚集。這類似於函數語言程式設計語言中foldl函式。這個方法是憑藉呼叫codice_39方法實現的。例如：在第一個趟時，這個塊接受codice_37作為元素，結果為codice_45。codice_45接著成為在下一趟時的codice_43，這時向它加上codice_48得到codice_49。codice_49接著加上codice_51，最終返回codice_52。塊可以和很多內建方法一起工作，下面例子向一個檔案寫一行文字，然後再讀取它的每一行並顯示：(File name: 'file.txt') withWriteStreamDo:[ :file | file nextPutAll: 'Wrote some text.'; nl ](File name: 'file.txt') readStream linesDo:[ :each | each displayNl ] ; close"=&gt; Wrote some text."檔案類例項。串流類，它的codice_69方法關閉這個檔案。類.GNU Smalltalk建立新類採用特有的語法形式：超類名字 subclass: 新類名字 [| 諸例項變數 |pragmas訊息模式1 [ 諸語句 ]訊息模式2 [ 諸語句 ]類變數1 := 表示式.類變數2 := 表示式.]類似的，為現存的類擴充套件新方法採用特有的語法形式：類表示式 extend []在Smalltalk有關書籍中有一個常見版式約定，將一個類中的方法引用為codice_70，這不是Squeak/Pharo語法的一部份，GNU Smalltalk將codice_71作為定義類方法的語法形式。下面的程式碼定義叫做codice_72的一個類，這個類有兩個例項變數codice_73和codice_74，它們有各自的變異子與訪問子。定義了有兩個關鍵字引數的類方法，用來建立新的類例項。定義了單獨用codice_74來進行比較的codice_76方法，透過從codice_77派生，這個類自動繼承了所有的其他比較方法的定義。這個類還透過覆寫codice_10的方式，定製了這個物件的列印方式：Magnitude subclass: Person [| name age |Person class » name: name age: age [^self new name: name; age: age; yourself 5"在因異常狀況而要進入偵錯程式，可以呼叫物件類的codice_93方法，或增加了一個訊息引數的codice_94方法；這二者實際上呼叫了物件類的codice_95方法，它透過原始操作停止執行啟動偵錯程式，並展示這個錯誤訊息：self halt. "halt encountered"self halt: 'This is a message'.self error: 'This is a message'