history

青木日記 RSS

<前の日 | この月 | 次の日>

2005-12-04

Distribution.Compat.FilePath

なんで FilePath がエクスポートされてないんじゃあああああああああああ! 存在するのに使えないってメチャクチャ腹立つよ!

しょうがないので必要なやつだけ適当に書いといた (かなり用途特化ぎみ)。

module PathUtils
    (concatPath, joinPath, basename, dirname, components, ancestors)
where
 
import Data.List (intersperse)
 
concatPath :: [String] -> String
concatPath []   = "/"
concatPath [""] = "/"
concatPath cs   = join "/" cs
 
joinPath :: String -> String -> String
joinPath a b
    | null a        = '/' : b
    | last a == '/' = a ++ b
    | otherwise     = a ++ "/" ++ b
 
basename :: String -> String
basename "/"  = "/"
basename path = last (components path)
 
ancestors :: String -> [String]
ancestors path = case scanl1 (joinPath) $ components path of
                   ("":xs) -> reverse ("/":xs)
                   xs      -> reverse xs
 
components :: String -> [String]
components = split '/'
 
dirname :: String -> String
dirname "/" = "/"
dirname path = case components path of
                 []  -> ""
                 [_] -> "."
                 cs  -> concatPath (init cs)
 
split :: Char -> String -> [String]
split _ [] = []
split sep str = word : split sep cont
  where
    (word, cont') = break (==sep) str
    cont = case cont' of
             []     -> ""
             (c:cs) -> cs
 
join :: String -> [String] -> String
join sep = concat . intersperse sep

ところで、この日記の記法だと Haskell のコメントが pre に入れられないことが判明した。 BitChannel と同じく {{{ ... }}} 記法を実装するべきか。

はじめての HUnit

HUnit、記述がめちゃうざったい……。 関数名を三回書かないといけないのもさることながら、 頭の runTestTT なんたらもさることながら、 assert のメッセージ書くのがあまりにめんどい。 あまりにめんどくさいので番号にしてしまった。 やっぱりこういうとこは Ruby のほうが圧倒的に気楽でいいなあ。

import Test.HUnit
import PathUtils
 
main = runTestTT $ test $
    [ "test_ancestors"  ~: test_ancestors,
      "test_components" ~: test_components,
      "test_concatPath" ~: test_concatPath,
      "test_joinPath"   ~: test_joinPath,
      "test_basename"   ~: test_basename,
      "test_dirname"    ~: test_dirname ]
 
test_ancestors =
    do assertEqual "1" ["/"] (ancestors "/")
       assertEqual "2" ["/a", "/"] (ancestors "/a")
       assertEqual "3" ["/a/b", "/a", "/"] (ancestors "/a/b")
       assertEqual "4" ["/a/b", "/a", "/"] (ancestors "/a/b/")
       assertEqual "5" ["a/b", "a"] (ancestors "a/b")
       assertEqual "6" ["a/b", "a"] (ancestors "a/b/")
       assertEqual "7" ["a"] (ancestors "a")
 
test_components =
    do assertEqual "1" [""] (components "/")
       assertEqual "2" ["", "a"] (components "/a")
       assertEqual "3" ["", "a", "b"] (components "/a/b")
       assertEqual "4" ["", "a", "b"] (components "/a/b/")
       assertEqual "5" ["a", "b"] (components "a/b")
       assertEqual "6" ["a", "b"] (components "a/b/")
 
test_concatPath =
    do assertEqual "1" "/" (concatPath [])
       assertEqual "2" "/" (concatPath [""])
       assertEqual "3" "/" (concatPath ["/"])
       assertEqual "4" "/a" (concatPath ["", "a"])
       assertEqual "5" "/a/b" (concatPath ["", "a", "b"])
 
test_joinPath =
    do assertEqual "1" "/a" (joinPath "/" "a")
       assertEqual "2" "/a/b" (joinPath "/a" "b")
       assertEqual "3" "a/b" (joinPath "a" "b")
 
test_basename =
    do assertEqual "1" "/" (basename "/")
       assertEqual "2" "a" (basename "/a")
       assertEqual "3" "b" (basename "/a/b")
       assertEqual "4" "a" (basename "a")
       assertEqual "5" "b" (basename "a/b")
       assertEqual "6" "." (basename ".")
       assertEqual "7" ".." (basename "..")
 
test_dirname =
    do assertEqual "1" "/" (dirname "/")
       assertEqual "2" "/" (dirname "/a")
       assertEqual "3" "/a" (dirname "/a/b")
       assertEqual "4" "/a/b" (dirname "/a/b/c")
       assertEqual "5" "a" (dirname "a/b")
       assertEqual "6" "." (dirname "a")
       assertEqual "7" "." (dirname ".")
       assertEqual "8" "." (dirname "..")

(02:50)

href 0.3

Haskell リファレンスマニュアル検索ツール href の 0.3 をリリースしました。

おかしい……原稿を書いていたところから転じて Wash のチュートリアルをやっていたはずが なぜ href をアップデートしているんだろう。

(02:51)

href 0.3.1

あー、そうだ、href の変更はこんなとこです。

  • リファレンスマニュアル増量 (Data.Maybe とか)
  • stdout が tty かどうかで出力形式が変わるようにした
  • 補完の精度向上

あとは外に変化の出ないリファクタリングとか。

それとビルドに GHC 6.4 が必要です。 うちのメインは Debian なので GHC 6.2 なんですが、 そっちだと URI の関数が足りなくてエラーになります。 (まあたいしたエラーじゃないのでそこだけ変えりゃ通ります)

……なんて書いているあいだに直したほうが早いなーと思いいたったので対応しておきました。

リリースから 3 時間もたってないよ……。 まあダウンロードした人はまだいないみたいだからいいか。

(04:04)

本日のツッコミ(全3件) [ツッコミを入れる]
shelarcy (2005-12-05 12:57)

darcs get http://www.scannedinavian.org/~lemmih/FilePath/

shelarcy (2005-12-05 13:16)

あっ、後 patch です。入れてくれてないので、適当にファイル名つけて darcs apply して下さい。


New patches:

[fixed joinFileName bug for "../" prefixed fileName and directoryName that endend non pathSeparator.
shelarcy@capella.freemail.ne.jp**20050907143754] {
hunk ./System/FilePath.hs 146
- | chr == '.' && isPathSeparator (head fname) = joinFileName (reverse $ dropWhile (not . isPathSeparator) $ reverse dir) (tail fname)
+ | chr == '.' && isPathSeparator (head fname) =
+ joinFileName (reverse $ dropWhile (not . isPathSeparator) $ dropWhile isPathSeparator $ reverse dir) (tail fname)
}

Context:

[change joinFilePath works well for file name that use "../" or "./" prefix. And added basename, dirname, dropFileExt (dropSuffix) functions that inspired by hs-plugins' function.
shelarcy@capella.freemail.ne.jp**20050907123002]
[CPP fixes from CosmicRay.
lemmih@gmail.com**20050721174613]
[Set me (lemmih) as the maintainer.
lemmih@gmail.com**20050721173849]
[Added LICENSE
lemmih@gmail.com**20050721173422]
[Initial record.
lemmih@gmail.com**20050426222116]
Patch bundle hash:
65a356504e79c8a892b310e80f1bcb1c4b0eb59d

青木 (2005-12-05 21:15)

む、なるほど、別配布になっているのですか。
ありがとうございます。
GHC に添付してほしいっすね……。

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|

Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved. LIRS