青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

用lisp開發博客客戶端

用lisp開發博客客戶端

Author: Kevin Lynx
Date: 3.13.2011

最近一直在學習Lisp這門語言。回頭一看,基本上接近1個月了。剛開始接觸Lisp是因為看 了<Lisp本質>,然后我發現有很多人宗教般地忠誠這門語言,于是就來了興趣。

imgs/lisp_believer.png

當然并不是每次因為某篇寫得很geek技術文章就去學習某個新的技術點。一個月時間對我來 說還是很珍貴了。但是Lisp絕對是大部分程序員都值得一學的語言(就像Haskell一樣)。 我能給出的簡單理由包括:

  • 大部分程序員只會命令式語言(C/C++/C Like etc),缺乏函數式語言解決編程問題的思 想(當然Lisp不是純函數式)
  • Lisp是僅次于Fortran的古老語言,很多優秀的語言設計思想在現代的一些語言里都找得 到
  • 裝B黨必備

另一方面,結合我一個月以來的讀書和兩個練習工程的實踐經歷,我覺得也有些理由值得你 不去學習Lisp:

  • 你會Haskell或者其他函數式語言
  • 我目前還是覺得Lisp學習曲線高(大概是因為我讀到的書都在應用語法層兜圈子,事實上 Lisp的語法之統一,全特么的是s-expression),你不愿意花費這些成本
  • you are too old bo to be a B

關于這篇文檔

這篇博客我使用reStructuredText格式編寫,然后用docutls導出為html,再然后使用這回 用lisp開發的基于metaweblog API的博客客戶端,自動發布到CPPBLOG。

他們怎么說Lisp

我就摘錄些書上的觀點(歷史):

  • 1958年,John McCarthy和他的學生搞出了Lisp,包括其第一個實現,最初貌似也是以一 篇論文起頭
  • Lisp可以讓你做其他語言里無法做的事情(<ANSI common Lisp>)
  • 大部分編程語言只會告訴你不能怎樣做,這限制了你解決問題的思路,Lisp not (<ANSI Common Lisp>)
  • Lisp讓你以Lisp的思維思考問題,換到其他語言你會說:為什么X語言就不支持這個特性 呢(Once you've leanred Lisp, you'll even dream in Lisp) (<Land Of Lisp>)
  • Lisp代碼更清晰地體現你的想法(<Practical Common Lisp>)

And my opinion

我可還沒到把Lisp捧上天的地步。如果Lisp如此之好,為什么用的人不多?<Land Of Lisp> 里作者恰好對這個問題做了回答(bla bla bla,懶得細讀)。

  • Lisp也是一門雜和型風格的語言,函數式、命令式、面向對象,以及最被人吹捧的宏編程 --程序自己寫自己
  • Lisp的語句全部以(xxx xxx)的形式出現,被稱為s-expression,我看稱為括號表達式還 差不多
  • Lisp每條語句都有返回值,沒基礎過函數式編程的同學,if語句也是有返回值的
  • 函數式編程語言的一個重要特性就是閉包(closure),這個東西用來避免全局變量實在太 geek了

開始學習Lisp

Lisp不像有些語言,有個直接的機構來維護。感覺它更像C/C++一樣,只有個標準,然后有 若干編譯器(解釋器)實現。Lisp在幾十年的發展中,產生了很多種方言。方言也就是形變 神不變的語言變種,本文說的Lisp均指Lisp的方言Common Lisp。另一個比較有名的方言是 Scheme,關于各個方言的特點,<Land Of Lisp>里也給了一個圖片:

imgs/dialect.png

其中,最左邊那只wolf就是Common Lisp,右邊那只sheep就是Scheme。

要學習Lisp,首先就是選擇方言。然后最重要的就是選擇一個編譯器實現。世界上知名的有 十幾種實現(也許更多)。一些商業版本非常強大,甚至能編譯出很小的本地代碼執行文件 ,不過價格也不菲。當然也有很多開源免費的實現,例如CLISP、SBCL。我選用的是SBCL。

SBCL交互式命令行不支持括號匹配,甚至沒有輸入歷史。要實現這兩個功能,可以裝一個 lisp工具:linedit。在lisp的世界中,要獲得一個lisp的庫實在不是件方便的事。尤其是 這些免費的編譯器實現,并不像有些語言一樣,直接隨編譯器帶個幾十M的庫。

然后就有了quicklisp這個工具。該工具就像Ubuntu系統里的軟件管理器一樣,你可以在 lisp里直接獲取某個庫。quicklisp檢查該庫是否存在,不存在直接從它的服務器上下載人 然后自動安裝。

此外,在lisp的世界里,寫出來的程序不再是跨OS。OS的差異由編譯器實現來解決。但是, 寫lisp程序卻需要考慮跨編譯器實現(egg hurt)。這也是個無比傷神的事,比跨OS更傷 神。因為OS就那么幾個,但lisp的編譯器實現,流行的也有好幾個。

lisp的世界里,工程組織也有特殊的一套,就像makefile一樣,這就是asdf。

博客客戶端如何實現

像我們這種基本沒接觸過Web開發的人,可能完全沒有思路去實現一個博客客戶端。事實上 實現起來非常簡單。

使用過其他博客客戶端(例如Windows Live writer)的人肯定知道metaweblog API,在配 置客戶端的時候需要填入。例如CPPBLOG的這個地址就是 http://m.shnenglu.com/kevinlynx/services/metaweblog.aspx。這個頁面展示了一些API 說明。這些API就是博客客戶端和服務器進行操作通信的接口。意思是說,服務器端提供這 這些接口,我們的客戶端調用這些接口即可。例如:

blogger.deletePost,調用該接口即可刪除一篇博客文章

但是客戶端如何調用到這個接口呢?這需要通過一種新的技術(或者說標準),即 xml rpc 。rpc大家應該清楚,xml rpc其實說白了, 就是把接口調用的細則塞進 http 請求發給web服務器,服務器接收請求完成操作后再把結果以http回應的形式丟給客戶端, 即完成了一次接口調用

至于http請求回應的細則就不提了,無非就是一些特殊格式的數據,通過tcp連接與服務器 交互這些數據。

所以,基本上,整個過程還是非常簡單。如何來將調用細節塞進http請求,則是以xml rpc 標準來做,其格式正好是xml格式。舉個例子吧:

<?xml version='1.0'?>
<methodCall>
    <methodName>title_or_id</methodName>
        <params>
        </params>
</methodCall

當然這部分數據之前就是若干http請求的數據。服務器回應也是以xml格式組織:

<?xml version='1.0'?>
<methodResponse>
    <params>
        <param>
            <value><string>Welcome to Zope.org</string></value>
        </param>
    </params>
</methodResponse>

我們的博客客戶端所要做的,就是把這些博客發布相關的操作封裝起來提供給使用者。底層 實現主要包括http請求、xml-rpc的組織等。何況,這兩部分在各個語言里都有大量的庫存 在,lisp自然也有。

我這里直接選取了lisp的一個xml-rpc庫:s-xml-rpc,基本上百來行代碼就可以把各個功 能跑一遍。例如以下lisp代碼就實現了通過s-xml-rpc刪除CPPBLOG的一篇文章:

(defun delete-post (postid)
  (rpc-call
    "blogger.deletePost"
    postid
    "kevinlynx"
    "password"
    t))

發布博客也很簡單,根據metaweblog API接口的說明,發布博客時需要填充一個結構體。但 主要涉及到的數據僅包括:文章內容、文章標題、文章分類(可選):

(defun new-post (title context &optional (cates))
  (rpc-call
    "metaWeblog.newPost"
    ""
    "kevinlynx"
    "password"
    (new-post-struct title context cates)
    t))

值得注意的是,如果文章中有貼圖,則需要事先將圖片文件上傳到服務器。CPPBLOG的 metaweblog API里恰有API提供:

(defun new-media-object (filename)
  (rpc-call
    "metaWeblog.newMediaObject"
    ""
    "kevinlynx"
    "password"
    (new-media-object-struct filename)))

該函數讀入圖片文件,然后調用metaWeblog.newMediaObject接口,即可完成上傳。上傳成 功后,服務器會返回該圖片的URL。然后在我們的文章中就可以使用該圖片了。

完整實現方案

僅僅將metaweblog的一些接口做封裝,對于一個可以使用的博客客戶端來說還遠遠不夠。大 部分同類工具都有一個友好的GUI編輯界面。我并不打算弄一個編輯界面出來,吃力不討好 的事情。

我的打算是先用其他工具對文章做排版處理,最后導出為html格式。因為CPPBLOG支持直接 發布一個html文件。然后在用這個lisp工具將整個文件作為博客文章內容發布。

恰好公司最近打算用reStructureText(rst)格式來編輯文檔,作為熟悉手段,我決定拿這個 來練手。rst格式非常簡單,同wiki命令很相似。在vim里編輯該文件非常合適,因為默認支 持。見圖:

imgs/rst.png

由圖即可看出,rst是一種半所見即所得的格式。即:它遵循你在編輯器里的排版,同時也 通過一些tag(例如image)來控制更豐富的輸出。

rst有很多前端工具,可以將rst文件輸出,例如rst2html.py就可以輸出為html。好吧,最 最終我們得到了html格式的博客文章。

但是如果文章中出現了圖片,而圖片基本上在本地,轉成html后也是相對路徑。我需要我的 lisp writer(cl-writer)能自動掃描文章,發現有圖片的地方,就自動將圖片上傳。最惡心 的是上傳后還得替換圖片引用路徑。這個工作可以在rst格式上做,也可以在結果格式html 上做。通過xml解析庫解析html比直接解析rst格式更簡單,并且在擴展性上更好。

最終這個html中圖片路徑替換工作只消耗了不到100行lisp代碼。這在很大程度上也依賴于 s-xml庫的接口設計。

最終封裝好的發布接口如下,從這里也可以看出,函數式語言鍛煉我們寫出功能單一代碼度 短小的接口:

(defun writer-post-new (post-file &key (u (get-default-user))(cates))
  (read-post-file u post-file context title
                  (new-post u title context cates)))

END

別指望我發布的代碼能夠讓你一鍵在你的博客上留下"this is a test",你甚至別指望它能 能夠工作。但如果你本來就是一個資深的lisper,或者雖然不是lisper但卻執意想看看結果 。這里我就簡要說說如何讓這些代碼歡樂起來:

  1. OS Ubuntu10.04,下載安裝SBCL,不會有問題;

  2. 下載安裝quicklisp,官方文檔hand by hand,簡單不會有問題;

  3. SBCL交互環境中使用quicklisp安裝s-xml-rpc:

    (ql:quickload "s-xml-rpc")
    
  4. 裝載我的代碼:

    (asdf:load-system :cl-writer)
    
  5. 在home下添加配置文件.cl-writer.lisp,配置你博客信息,例如:

    (in-package cl-writer)
    (setf *default-user* (make-cppblog-user "賬戶名" "密碼"))
    

    如果你的博客不在CPPBLOG,雖然也許也是metaweblog,但我不能保證成功,配置文件則 要復雜點:

    (setf *default-user* (make-user-info :name "帳戶名"
                          :password "密碼" :host "m.shnenglu.com"
                          :url "/kevinlynx/services/metaweblog.aspx"))
    
  6. SBCL交互環境下測試:

    (in-package cl-writer)
    (new-post (get-default-user) "this is a test" "title")
    

下載代碼

最后,終于敲完這篇文章,我需要通過以下步驟來發表它:

in shell:
rst2html.py lisp_xml_rpc.rst lisp_xml_rpc.html
in SBCL:
(writer-post-new "lisp_xml_rpc.html")

;;EOF;;

posted on 2011-03-13 13:19 Kevin Lynx 閱讀(16907) 評論(8)  編輯 收藏 引用 所屬分類: lisp

評論

# re: 用lisp開發博客客戶端 2011-03-13 20:04 ccsdu2009

寫的不錯 很好的寫手!  回復  更多評論   

# re: 用lisp開發博客客戶端[未登錄] 2011-03-14 10:30 Louis

CLISP 我也折騰過不短的時間,當然沒有用到真正的工作上。最主要的是這個括號匹配,實在是太蛋疼。  回復  更多評論   

# re: 用lisp開發博客客戶端 2011-03-14 13:18 Kevin Lynx

@Louis
閱讀Lisp代碼主要是通過代碼縮進來識別語句關系,如果是通過括號那根本沒法閱讀。在RECL下(也就是交互模式下)輸入語句我喜歡一行輸下去,所以那個輸入環境能有括號匹配(例如CLISP輸入")"時就會做點提示)就是個不錯的功能。SBCL默認沒有。  回復  更多評論   

# re: 用lisp開發博客客戶端 2011-03-14 21:51 Albert Lee

sbcl 可以配合 rlwrap 來實現 readline 功能。 現在很流行一個安裝lisp庫的工具: quicklisp , 非常方便。 另外,在實際開發Lisp的時候, Emacs + Slime 是一個非常強大的工具,邊開發邊執行邊改進,最能體現Lisp的快速迭代演進的開發風格。  回復  更多評論   

# re: 用lisp開發博客客戶端 2011-04-25 22:34 hex108

太帥了!
image:: imgs/lisp_believer.png 也是我想要的功能  回復  更多評論   

# re: 用lisp開發博客客戶端 2011-09-01 12:58 xiaohanyu

太帥了!!!  回復  更多評論   

# re: 用lisp開發博客客戶端[未登錄] 2012-02-23 17:52 li

@Albert Lee
但是在開發一個項目的時候感覺就不是很方便
目前在學習lisp中 希望多交流交流 嘻嘻  回復  更多評論   

# re: 用lisp開發博客客戶端 2014-09-04 00:45 leptune@live.cn

鼓搗了一晚上,終于用樓主的代碼成功的將博客發送的新浪博客了!!謝謝樓主!
幫樓主步驟補充詳細些,以幫助那些跟我一樣的小白:
如果提示asdf沒發現,那么是你少了(require 'asdf)
如果提示cl-writer沒發現,那么就:sudo cp cl-writer.asd /usr/local/lib/sbcl/contrib/
最后發表的總步驟為:
(ql:quickload "s-xml-rpc")
(asdf:load-system :cl-writer)
(in-package cl-writer)
(writer-post-new "lisp_xml_rpc.html")
新浪博客的配置文件為:
(setf *default-user* (make-user-info
:name "281754179@qq.com"
:password "密碼"
:host "upload.move.blog.sina.com.cn"
:url "/blog_rebuild/blog/xmlrpc.php"))  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲美洲欧洲综合国产一区| 国产精品稀缺呦系列在线| 欧美va亚洲va香蕉在线| 欧美亚洲一区二区在线观看| 夜夜嗨一区二区| 日韩一二三在线视频播| 99v久久综合狠狠综合久久| 怡红院精品视频在线观看极品| 国产精品日韩久久久久| 韩国精品在线观看| 亚洲精品国产品国语在线app| 亚洲精品在线视频观看| 亚洲欧美日本日韩| 久久永久免费| 亚洲一区二区三区高清| 欧美一区亚洲二区| 欧美激情亚洲| 国内精品一区二区| 亚洲一区二区三区免费视频| 久久国产精彩视频| 亚洲精品影院| 老司机精品福利视频| 欧美视频在线视频| 亚洲国产精品999| 久久精品国产69国产精品亚洲| 欧美二区在线播放| 欧美一区中文字幕| 国产精品免费网站| 亚洲综合色丁香婷婷六月图片| 免播放器亚洲一区| 亚洲国产美国国产综合一区二区| 久久精品国产清高在天天线| 亚洲激情在线视频| 久久人人97超碰国产公开结果 | 麻豆久久婷婷| 久久久99爱| 伊人一区二区三区久久精品| 亚洲一区欧美激情| 香蕉久久久久久久av网站| 国产精品日韩一区二区三区| 亚洲调教视频在线观看| 亚洲欧美日韩在线一区| 国产女人精品视频| 久久免费视频在线观看| 裸体歌舞表演一区二区| 亚洲国产欧美一区二区三区丁香婷| 欧美成年人视频| 欧美日韩国产色站一区二区三区| 亚洲色图在线视频| 亚洲欧美国产日韩中文字幕| 国产午夜精品一区二区三区视频| 久久精品免费| 欧美日韩性视频在线| 久久www免费人成看片高清| 麻豆成人在线播放| 亚洲一区二区三区高清不卡| 久久黄色网页| 亚洲欧美日韩国产一区二区三区| 久久久久久夜| 新片速递亚洲合集欧美合集| 欧美大片免费观看在线观看网站推荐| 在线中文字幕不卡| 欧美成人免费全部| 欧美成人资源| 一区在线观看视频| 欧美在现视频| 欧美激情中文字幕乱码免费| 欧美在线三区| 国产亚洲欧美一区| 亚洲一区精品电影| 亚洲综合国产精品| 国产精品久久9| 亚洲图片欧美午夜| 亚洲午夜一级| 国产精品综合久久久| 这里只有精品视频在线| 亚洲主播在线观看| 国产精品久久久久久久久久尿 | 欧美日韩国产va另类| 欧美日韩国产一区精品一区| 欧美影院在线| 亚洲午夜伦理| 在线亚洲观看| 亚洲人成在线免费观看| 欧美伊久线香蕉线新在线| 久久不射中文字幕| 精品9999| 欧美日韩精品一区二区天天拍小说| 最近中文字幕日韩精品 | 亚洲无限乱码一二三四麻| 欧美.www| 亚洲综合第一| 亚洲国产日韩欧美一区二区三区| 亚洲欧美国产视频| 亚洲人成亚洲人成在线观看图片| 亚洲久久一区二区| 蜜臀久久99精品久久久画质超高清 | 欧美日韩国产欧| 毛片精品免费在线观看| 亚洲一区欧美| 夜夜嗨av一区二区三区网站四季av| 欧美一区二区三区免费观看| 一区二区三区色| 亚洲精品国产精品乱码不99按摩| 激情视频亚洲| 亚洲电影观看| 欧美午夜久久久| 亚洲精品综合精品自拍| 99re66热这里只有精品3直播| 亚洲欧美日韩一区二区三区在线观看| 久久激情五月婷婷| 欧美成人国产| 欧美人与性禽动交情品| 欧美性猛交xxxx乱大交退制版| 欧美性猛交xxxx乱大交蜜桃| 国产精品久久午夜夜伦鲁鲁| 欧美视频二区36p| 国产精品va在线| 国产三级精品三级| 亚洲国产婷婷综合在线精品| 亚洲国产毛片完整版| 一区二区欧美国产| 亚洲欧美乱综合| 欧美激情影音先锋| 亚洲一级二级在线| 免费久久久一本精品久久区| 欧美日本在线看| 欧美日韩另类在线| 伊人夜夜躁av伊人久久| 亚洲欧美电影在线观看| 模特精品在线| 久久久成人精品| 欧美视频一区二区三区| 国产农村妇女精品一二区| 中文日韩电影网站| 久久精品综合| 国产在线精品一区二区夜色| 亚洲日韩第九十九页| 毛片一区二区三区| 亚洲免费视频成人| 欧美日韩免费看| 亚洲人成精品久久久久| 另类尿喷潮videofree| 欧美一区二区三区视频在线 | 欧美一区国产二区| 国产视频一区在线观看一区免费 | 亚洲视频专区在线| 国产精品女主播| 亚洲高清av在线| 欧美高清自拍一区| 免费观看成人鲁鲁鲁鲁鲁视频| 国产日韩欧美日韩| 久久久久高清| 久久综合九色99| 亚洲精品一区二区三区av| 亚洲国产一区二区a毛片| 欧美激情一二三区| 亚洲一区二区三区免费观看 | 激情av一区二区| 久久乐国产精品| 免费观看亚洲视频大全| 亚洲激情黄色| 亚洲欧美国产制服动漫| 激情小说另类小说亚洲欧美 | 正在播放欧美视频| 亚洲专区免费| 亚洲人成网站在线观看播放| 亚洲狼人精品一区二区三区| 国产精品一区二区视频| 国产精品久久久久9999| 亚洲欧美日韩在线一区| 久久国产精品99国产精| 国模叶桐国产精品一区| 亚洲高清视频的网址| 欧美中在线观看| 欧美日韩国产高清视频| 久久人人爽国产| 国产精品劲爆视频| 亚洲日本中文字幕区| 在线成人h网| 欧美一区激情| 亚洲欧美在线一区二区| 欧美精品999| 亚洲人成网站影音先锋播放| 精品1区2区3区4区| 亚洲综合国产激情另类一区| 亚洲麻豆视频| 欧美激情第4页| 亚洲黄色尤物视频| 日韩午夜在线| 欧美日韩亚洲视频| 一级日韩一区在线观看| 在线视频一区二区| 国产精品久久久久9999| 亚洲制服av| 亚洲高清久久| 亚洲一区在线看| 国产一区日韩欧美| 久久影视精品| 亚洲伦理网站|