「這看起來至關愚蠢」——題記python
不過我整我的都很荒誕,何妨呢?貼一張目前的效果圖git
看起來很舒服,不是麼?即便一切都是個幌子:光標只能在最後,按一下上下左右就會退出,一行超出75個字符就會連帶行號消失,打完36行程序就會奔潰——並且不能保存,彷彿一臺玩具打字機。但這又怎麼樣?我喜歡!我想把它放到github上去——可是恐怕隨時得回滾,因此算了吧。github
我歷來不在意開發,我在意的是哲學,一切空談在我眼裏都是有價值的。因此,我剛開始寫的時候,我在想什麼?小程序
——我在想,我要寫個命令行編輯器——那是什麼東西?——就是一個命令行界面,每敲一個鍵就變化一點——而且按傳說中MVC的作法,要有個模型,在這裏惟一的參數就是包含整個文本的字符串——因此主循環就是顯示字符串→接收輸入→更新字符串。每一步均可謂開銷巨大(以致於給人以罪惡感),但如今不是優化的時候——如今能夠寫個大體了。給出目前爲止的代碼:(某版本真實代碼)數組
screen = "" while True: show_screen() ch = getch() update(ch)
不能運行,並不重要。事實上咱們發現這是一個狀態機(字面義)——而這裏的狀態僅僅是screen字符串的狀態。簡單的結構是使人欣慰的。(我看了一眼代碼,以爲應該在 show_screen() 和update(ch)的括號裏都添上screen)編輯器
(半天過去了)ide
單行長文本bug解決了。(雖然說我就從沒寫過超過一行的代碼)函數
(又過去了一天)優化
重寫了邏輯,依然混亂。因此先發表吧。命令行
(2018-1-1 於地球,未完)
問題通常化:【怎樣寫出一個命令行程序?】
既然是一個狀態機,咱們固然能夠列出一個狀態表,屏幕每次由狀態刷新(#),動做將改變狀態。對於命令行,僅有的動做就是擊鍵,並且是有限個。動做響應也是離散的,一次擊鍵只須要變更一次屏幕(#)。我先不談文本編輯器,此前的一個小程序很好地符合了這些思想——一個九宮格走迷宮的程序(雖然當時我尚未模型意識)。9個房間,左轉右轉或前進。狀態是有限的,只有有限個位置能夠站。因此咱們能夠列出一張表:
動做1 | 動做2 | 動做3 | …… | |
---|---|---|---|---|
狀態1 | 操做11 | 操做12 | 操做13 | …… |
狀態2 | 操做21 | 操做22 | 操做23 | …… |
狀態3 | 操做31 | 操做32 | 操做33 | …… |
…… | …… | …… | …… | …… |
而顯示與狀態是惟一對應的。因此理論上填完這張表,問題就解決了。但這是不現實的,連那個走迷宮程序這張表都不適用,由於狀態的「組合爆炸」。在走迷宮程序中,狀態是由「所在房間」和「正對方向」2個參數組合而成的,而且一切都是臨時組合,也所以有些組合不可到達。而在編輯器的例子中,組合甚至是無窮的!在我如今處理的版本中,雖然只有字符串一個參數,但足以形成無限的狀態。因此……
應當看作同一個狀態。
我想到了「化歸」,更確切一點是「等價劃分」。將若干個甚至無窮多狀態看做同一狀態。在編輯器中,全部的編輯都是同一個狀態。當加入光標左右移動,光標在中間的時候是等價的,只有在兩端纔可能出現特殊狀況,因此能夠劃分爲3個等價狀態……可是開發是一個過程,咱們一開始固然想不到這麼多,怎麼處理呢?——漸進或許是個好辦法。在初始版本(單行打字機)中,邏輯是這樣的:
26字母(分大小寫)和空格 | |
---|---|
編輯狀態 | 將接收到字符添加到字符串尾部 |
少量改進後是這樣的:
26字母(分大小寫)和空格 | 退格 | |
---|---|---|
編輯狀態 | 將接收到字符添加到字符串尾部 | 刪除字符串最後一個字符 |
這種表沒法表示實際顯示,但實際顯示既然是狀態的惟一函數,也不用擔憂邏輯問題……雖然說簡直沒有實用價值,但這麼分析至少帶給人好處。
(又過去一天,我要重寫代碼……)
(2018-1-9 於地球,未完)