トップ «前の日記(2008-08-21) 最新 次の日記(2008-08-25)» 編集

Route 477



2008-08-23

[ruby] bitclustに関するメモ

Ruby合宿中に聞いとけばよかった…。

ディレクトリ構成はとりあえず

% ls
bitclust/
doctree/
db-1_8_7/

みたいにする。

まずDBフォルダを作る。

% ./bitclust/bin/bitclust.rb -d ./db-1_8_7 init version=1.8.7 encoding=euc-jp

encoding=utf8とかしても、入力を自動的にUTF8に変換してくれたりはしないので注意(今のところ)。

次にリファレンスを読み込む。svn upを忘れずにな。

% ruby -I bitclust/lib/ bitclust/bin/bitclust.rb -d ./db-1_8_7/ update --stdlibtree=./doctree/refm/api/src

末尾に「&& echo ^G」(^GはC-v C-g)とかしとくと終わったときにベルが鳴って良い。「&& say 'finished'」でもいいけど(Mac限定)。

んでサーバ起動。

% ./bitclust/standalone.rb --debug --database=db-1_9_7 --port=10081 --baseurl=""

--debugを付けないと^Cで止められないので注意。

ここまではいいんだ。ここまでは。

ツリーの一部分だけ更新したい

えーと

一部分だけやろうとするとOpenSSLあたりのドキュメントでエラーになるんでDB作るところからやり直さんといかんのだが、 リファレンス書くだけならbc-tohtmlで部分的にHTML作ればいい気がしてきた。

Tips

bitclust/theme/default/style.cssで s/33a/3a3/g とかすると、デザインが青から緑になるのでローカルだとわかりやすくなって良い。

[haskell] ParsecでS式をパーズしてみた

てか48時間Scheme(via http://kzk9.net/column/haskell_parsec.html)そのままだが。

import Text.ParserCombinators.Parsec

data Value = IntValue Int | StrValue String | ListValue [Value]
  deriving (Eq, Show)

parseSexp :: Parser Value
parseSexp = parseAtom
        <|> parseList

parseAtom :: Parser Value
parseAtom = parseInt
        <|> parseStr

parseInt :: Parser Value
parseInt = do s <- many1 digit
              return $ IntValue (read s)

parseStr :: Parser Value
parseStr = do char '"'
              x <- many stringParts
              char '"'
              return $ StrValue $ concat x
  where 
    stringParts :: Parser String
    stringParts = do c1 <- char '\\' 
                     c2 <- anyChar
                     return $ c1:[c2]
              <|> do c <- try $ noneOf "\""
                     return $ [c]

parseList :: Parser Value
parseList = do char '('
               ls <- sepBy parseSexp (skipMany1 space)
               char ')'
               return $ ListValue ls

main = print $ parse parseSexp "" "(\"1\" (2) 3)"

値をValueで包まんといかんのが嫌なんだが、なんとかならんかなぁ。

IntとStringだけでよければ型クラス?でなんとかなりそうな気がするが、それらのリスト(とリストのリストとか)をどうしたらいいのかわからん。

[ruby] Rubyライブラリのサンプルコードを書くときのTips

Rubyのライブラリは大抵、

bin/ (あれば)
lib/foo.rb
lib/foo/bar.rb
test/test_foo.rb
example/baz.rb

みたいになるわけだが、example/baz.rbからlib/foo.rbをrequireするにはどうすればいいか?という問題がある。

もちろん、インストールしてしまえば

require 'foo'

でいいわけだが、開発中はそういうわけにもいかない。

「サンプルコードはトップレベルで実行してね」(または、example以下で実行してね)と決めてしまえば、

require 'lib/foo'

とか

require '../lib/foo'

でrequireできるが、これだと決められたディレクトリで実行しないとLoadErrorになってしまう。

そこで、example/baz.rbの最初に以下のように書いておくと、どこから実行しても require 'foo' でいけるようになる。

$LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))

何をしているかというと、__FILE__で自分自身(つまりexample/baz.rb)のパスを取得して、baz.rbのある ディレクトリから ../lib を相対的にたどり、requireがライブラリを探す対象として登録している。

(8/26追記: 場合によっては、$LOAD_PATH << より $LOAD_PATH.unshift の方が良いかも。<<は末尾に追加するので、fooというライブラリが既にインストールされてたりするとそっちを読みこんでしまう。)

ちなみにこのTipsはサンプルコードだけでなく、ユニットテストにも使える。

$LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
require 'rspec'
require 'foo'

とかね。

[haskell] HaskellでS式のライタを書きたいんですけど

とりあえず IntとStringと[a]をSexpValueのインスタンスにしようとしたんですけど、String(つまり[Char])と[a]がバッティングして動いてくれません(><)

{-# OPTIONS_GHC -XTypeSynonymInstances #-}                                               
{-# OPTIONS_GHC -XFlexibleInstances #-}                                                  
{-# OPTIONS_GHC -XFlexibleContexts #-}                                                   
import Data.List                                                                         
                                                                                         
takeChars :: String -> [Int] -> [String]                                                 
takeChars str ns = map (\n -> [str !! n]) ns                                             
                                                                                         
class SexpValue a where                                                                  
  toSexp :: (SexpValue a) => a -> String                                                 
instance SexpValue Int where                                                             
  toSexp n = show n                                                                      
instance SexpValue String where                                                          
  toSexp s = show s                                                                      
instance SexpValue a => SexpValue [a] where                                              
  toSexp ls = "(" ++                                                                     
              (concat $ intersperse "," (map toSexp ls)) ++                              
              ")"                                                                        
                                                                                         
main = putStr $ toSexp $ takeChars "abcde" [1,3]   

どうしたらいいんだろう。Showとかはどうやってるのかな。

[vim][mac] Vim.appがうまく動かない

  • 新しくファイルを開いてインサートモードに入ると、なぜかIMEがオンの状態になる(オフであってほしい)
  • UTF-8のファイルで「\」キーを押すと円マークが入力されてしまい、バックスラッシュが入力できない。(\nが書けなくて困る)
  • インサートモードでBSを押しても、入力を開始した地点より前が削除できない

設定でなんとかなるんだろうか…。。

(8/29追記: 1番目は~/.vimrcに set iminsert=0 と set imsearch=0 を追加したら直りました。ありがとうございます>znzさん)

本日のツッコミ(全9件) [ツッコミを入れる]
星一 (2008-08-23 18:05)

実行時に -I オプション付け足すのでは駄目なんでしょうか。

minke (2008-08-23 18:26)

http://haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-Show.html<br>Show クラスの中に showList というメソッドが用意してあって、デフォルトでは各要素を [ , , ] で括るようになっているけど、instance Show Char の中でこれを書き変えてありますね。<br>instance Show a => Show [a] の中で showsPrec が a型の showList 使って実装されているので、特定の型のリストに対して特別な挙動をさせることが可能になるという仕組みのようです。トリッキーですね。

k.inaba (2008-08-23 18:31)

-XOverlappingInstances でどうでしょう。<br>http://www.kotha.net/ghc_users_guide_ja/type-class-extensions.html#instance-overlap

yhara (2008-08-23 20:29)

星一さん:<br>ああ、その手がありましたね。確かに。<br>その場合もディレクトリを意識しないといけないので、(面倒くさがりな)僕はよくこうしてます。

znz (2008-08-24 02:08)

vimのIMEが勝手にオンになるのはset iminsert=0 imsearch=0とかでどうでしょうか?

yhara (2008-08-25 14:14)

minkeさん:<br>おお、そういう風になっていたのか…。僕も頑張って読んでみます。<br>k.inabaさん:<br>ありがとうございます。試してみたのですが、今度はリストのリスト(具体的には[[Int]])の中の数値リテラルの型が曖昧だと怒られるようになりました。<br>もうちょっと試行錯誤してみます。<br>---<br>foo.hs:24:28:<br> Ambiguous type variable `t' in the constraints:<br> `Num t' arising from the literal `1' at foo.hs:24:28<br> `SexpValue t' arising from a use of `toSexp' at foo.hs:24:19-39<br> Probable fix: add a type signature that fixes these type variable(s)

b2ox (2008-08-26 11:22)

class SexpValue a where<br> toSexp :: (SexpValue a) => a -> String<br> toSexpList :: (SexpValue a) => [a] -> String<br> toSexpList ls = "(" ++ (concat $ intersperse "," (map toSexp ls)) ++ ")"<br><br>instance SexpValue Int where<br> toSexp n = show n<br>instance SexpValue Char where<br> toSexp c = show c<br> toSexpList s = s<br>instance SexpValue a => SexpValue [a] where<br> toSexp l = toSexpList l<br><br>こんな感じにしてやると、<br>*Main> toSexp [["abc","def"],["ghi","jk"]]<br>"((abc,def),(ghi,jk))"<br>*Main> toSexp [[[1,2],[3,4]],[[5],[6],[7::Int]]]<br>"(((1,2),(3,4)),((5),(6),(7)))"<br>みたいになります。

Yuya (2008-09-01 00:32)

バックスラッシュの入力は、Alt + バックスラッシュでいけたりしませんかね?<br>いや、試していないのですが・・・

yhara (2008-09-01 04:06)

b2oxさん:<br>ありがとうございます。なるほど、7::Intのように型を明示的に指定してやればいいんですね。<br>Yuyaさん:<br>おおおできた!Altは押しにくいですけど日本語IMを経由するよりはだいぶ楽でいいですね:-)