#ありがとうございます。js.scm で十分かも。
#DNFに懲りずに100kmのトレイルレースに申し込んでしまった
#がんばってトレーニングしないと絶対完走できないな...
#Gaucheって __FILE__ 的なものってあるんでしょうか。探してみたけどみつからなかった、、、
#それは昔ちょっと要望が出たことがあるんですが、Cプリプロセッサとセマンティクスが違うのでうまくいかないんです。
#ソースコード上の位置はextended pairに記録されているのでそれを取ることはできます。
#で、自分自身のソース名と行番号を取れるマクロ (例えば (__FILE__)) も書ける。
#ところが、この__FILE__の使用を隠すためにもう一段マクロをかますと
#例えば (define-macro (MALLOC x) `(debug-malloc ,x (__FILE__) (__LINE__)))
#Cプリプロセッサ的にはMALLOCを実際に使った場所の__FILE__, __LINE__を取れることを期待するわけですが
#「ソース上の」__FILE__, __LINE__の位置はMALLOCマクロの定義された位置であって、MALLOCマクロがどこで使われるかとは関係ない
#わけなので、役に立たなかったと。
#もしGaucheで書くのなら、「マクロに渡されたフォームのソースコード情報を抜き出して使う」ようなマクロにする必要がありますね。
#たしかに、↑のdebug-mallocの例だとそうですね
#gosh> (define-macro (with-srcinfo form) `(,(car form) ,@(cdr form) (debug-source-info ',form)))
#<undef>
gosh> (define (test lis srcinfo) (print lis "@" srcinfo))
test
gosh> (begin (with-srcinfo (test '(1 2 3)))
(with-srcinfo (test '(4 5 6)))
(with-srcinfo (test '(7 8 9))))
(1 2 3)@((stdin) 31)
(4 5 6)@((stdin) 32)
(7 8 9)@((stdin) 33)
#<undef>
#こんな方向でなんとかできるかもしれない。
#今やりたいことはもっと単純で、あるscmファイルAからloadしたいファイルBがあって、AからBへの相対パスだけはわかっていると。
#__FILE__的なものがあれば、Aの中から簡単にBのパスを計算できるかなと思ったんです。
#あ、それならそういうのがあります。
#どれだったかな。
#やっぱりありますか。絶対あるだろうとは思って探したんですけどみつからなくて。
#直接は取れないんですが、(port-name (current-load-port)) で(ファイルからロードされていれば) そのファイル名が取れます。
#ただし、ファイルからロードされてなかった場合にそうでないことを簡単に検出できないんですが
#文字列かどうか調べて、さらにそのファイルの存在を調べればほぼ大丈夫でしょう。
#おおお。これでいけそうです。ありがとうございます。
#そういえばこういう話の流れでload-relativeっていうのを作ろうかどうしようか考えたことがあったのを思い出した。
#結局どうしたんだっけな。loadのkeyword argumentでサポートするか、別関数にするか決めかねている段階で止まっていたような気がする。
##C++0x のラムダ式。
#構文は慣れの問題だろうけれど、lambda式の嬉しさのひとつは簡潔性だろうから、型を全部書かなきゃいけないとなると嬉しさ半減だなあ。型推論は入ってくれないのかなあ。
#型推論は一応 auto っていうのがはいるんですよね。
#あとは、template かな。
##Perl6 の演算子すごいですねぇ。
#非 ASCII 文字だけでプログラムかけそう。
#化けちゃってるっぽいんだけどutf-8で見れた?
#あ、はい。
#>>O”<< みたいな記号です。
#sub infix:<ö>($x, $y) { say "flyyy" }; (1,2,3) »ö« (4,5,6)
#お。貼れた。
#あれ、こっちだとちゃんと見える。
#これで絵文字もunicodeに入ったらカオスだな。
#化けているのかどうかの判断に、文化的背景が響いて来るかも
#でも、APLもそういうんじゃなかったけ? あと、初期のSmalltalkとか
#APLは一応文字セットは決まってたからなあ (そんなに多くない)
#タイプの「重ね打ち」でもって組み合わせができたから種類がたくさんに見えるけど
#たしかに、ちゃんと表示されていても文字化けに見える :D
#( ・ิω・ิ)これの眉毛とかも重ねうちですよね。
#Carbon Emacsに貼付けると化ける...
#Carbon Emacs はフランス語の ç とかは大丈夫なのかな?
#ああ、いやとおるさんのリンクの先をfirefoxで見ると、<Aの上ににょろっとした記号> <パラグラフ記号> のように見えるのですよ、演算子の部分が。
#utf-8にしてるんだけどなあ。
#sub infix:<ö>($x, $y) { say "flyyy" }; (1,2,3) »ö« (4,5,6)
#貼ってみた。こっちからだとやっぱり化けてる。
#Safari3でも化けて見えますね
#ああ、ぼくも、Google Reader でみるとそう見えます。
#sub infix:<ö>($x, $y) { say "flyyy" }; (1,2,3) »ö« (4,5,6)
#同じページにあるほかの文字に影響をうけるのかも。
#いけますね >ç
#UTF-8 でも、どの言語かの判断をまちがえると、正しいフォントが選ばれないんですよね。
#むー、でも上の化け方は本来1文字が2文字の扱いになってるので、フォントの問題ともちょっと違うような。とおるさんが貼ったオーウムラウトの方は一文字扱いになってる。
#http-getしてみたがちゃんとオーウムラウトで来てるなあ。
#Firefoxが何かしくじってるのかな。
#たしかに、Shift JIS みたいな化け方ですもんねぇ。
#ö
#öö
#öö
#あーでも、フォントによっては合字として実際には 2 字で表されることがあるのかも。
#lucille% echo -n "ö" | od -t x1
0000000 c3 b6
0000002
lucille% echo -n "ö" | od -t x1
0000000 c3 83 c2 b6
0000004
#メモリアクセスのバグかな?
#いや
#オーウムラウトをLatin-1として解釈してる。
#(Latin-1のc3 = Ã 、 b6 = ¶ )
#でもencodingはutf-8にしてるし、Page Infoでもそう出てるのにな。
#既出の話かもしれませんが
#あるファイルをuseした時はライブラリとして、gosh ファイル名 で起動した時にはコマンドとして機能するように書きたい時
#どうするのが一番オーソドックスなのでしょう?
#ああ、個人的にあんまりそういうニーズが無いのでちゃんと考えてなかったですね。
#kahua-server.scmがそれに近いことをしてるんだと思うんですが
#*program-name*を調べればいいかな。
#define-moduleして、select-moduleして、ライブラリの中身を書き、provideして(kahua-serverではやっていない)、(select-module user)してからmainを定義してる
#でもこれだと、useした時に、モジュールuserにmain関数が定義されちゃいますよね
#ああ、最後に(select-module user)してmainを定義する、っていうのは自分もよくやります。
#どうせ他のプログラムで使ったときはそいつのmainで上書きされるから無問題?
#useされるケースを想定してるわけじゃなくて、define-moduleしとくとtest-moduleでテストされるから便利というだけ
#ああなるほど
#userモジュールにmainを定義しちゃうと、ただloadしたいだけでも実行されちゃうからまずいんじゃないかな。
#< 他にuseされた場合、の話。
#ふむ
#useした時だけある関数定義を無効にするようなプラグマはある?
#いや、今のところ自分がuseで呼ばれたのかどうかってのはわからないですね。内部的にuseはloadを呼んでるし、コマンドラインでスクリプトファイルとして指定された場合もloadを呼んでるわけで。
#なるほどね
#*program-name*を調べるのも必ずしも安全ではないな。たまたまbasenameが同じ名前のスクリプトからuseされる可能性もある。
#current-load-historyを調べれば、自分が他のファイルを経由してloadされたのか、システムから直接loadされたのかはわかるけど
#-uオプションとかでuseされた場合は他のファイルを経由してないので、スクリプトファイルとしてロードされたのと区別できない
#ふむ
#案外一筋縄ではいかないですね
#[
#「スクリプトとして読んでますよ」フラグがあるのが一番すっきりするかなあ。
#mainを定義することはできないけれど、mainを定義しなくてもトップレベル式は評価されるので、
#(when (load-as-script?) スクリプト時の処理) と書いてしまうことはできる
#その場合、コマンドライン引数は *argv* 経由で処理?
#そうなりますね。mainの方が綺麗なんですけどね。
#もしくはcond-expandのfeatureとして見せてしまうか。
#スクリプトとして読まれたファイルのロード時のみ、gauche.script というfeatureが真になる。
#そしたら (cond-expand [gauche.script (define (main args) ...)] [else]) とか書ける。
#ロードの仕方によってfeatureが変わるのは微妙だけど。
#確かに、featureとするのは微妙な感じはしますね
#でもそれが一番すっきりする気もする
#最近、Gaucheの日本語infoのIndexだけ化けるなぁと思っていたら、昔/usr/local/binに野良ビルドして入れていたmakeinfoが悪さをした模様
#思わぬところに地雷がorz
#ありがち
#よし直った
#gauche.listener同士で会話させることを考えた場合、出力もバッファリングしてやるようにしないと、デッドロックする可能性ありますよね?
#そう。うー、頭の痛い問題だ。
#直接writeするのではなく、一度バッファに書き出した上で、
#with-output-to-stringでいったんプリンタの出力を受けて、write-blockか何かで出せるだけ出していく、って感じかな
#writableな時に一度だけ書くってのは出来たっけな。
#何か面倒な問題がどっかにあったような気がするんだけど
#今、gauche.listenerをつらつら眺めているんですが、string-append使ってたり、プログラム間で巨大なS式をやり取りするにはちょっと効率悪いかも?
#ああそうだ。flushは確実に全部のデータがwriteされるまで戻ってこない
#おお
#write-blockできたと思ってflushすると刺さっちゃうかも、か
#そうそう。
#bufferingをnoneにすればOK?
#ポートの
#いや、bufferingは途中のflushのタイミングを決めるだけで、
#ああそうか
#途中のimplicitなflushのタイミングを決めるだけで、明示的なflushは…
#うーん、それはまずいかも
#partial flushというか、「書けるだけ書いて、残りがあるかどうかの値を返してくれる」というapiがあるといいのかな。
#そうですね
#> string-append使ってたり: もともとプログラムにちょろっとREPLをつけて人間が使うような用途を考えてたんで、そこは手を抜いてあります。
#なるほど
#本格的にプログラム間の通信につかうなら、汎用的なバッファ構造を実装することになるでしょう。この機会にやっちゃってもいいかも。
#最初はgauche.listenerを使ってプロトタイプを書いて、パフォーマンスに問題が出るようなら根っこから書き直すという感じがいいかな
#S式の読み書きを安全にやりたいというのは、Kahuaに関わり始めてからずっと考えてました
#そうですね。その過程で現在のgaucheの足りない点を洗い出してもらえれば、対応します。
#partial flushはあると嬉しいかも
#listenerをうまく使うと、普通のインターネットアプリケーションが簡単に書けるなぁ、と考えているので
#例えばHTTPdとか
#パイプライニングのないものならたいてい書けちゃう
#もだんなHTTPdだとだめか orz
#fingerdとか(笑)
#ふーむ、listenerをそういうふうに考えたことはなかったなあ。
#sendmailとかpop3dにtelnetでつないでインタラクティブに使ったりすると、それがREPLに見えてきません?
#readとprintの部分が自動的にコルーチン化されて並行実行されるのがアドバンテージか…でもevalの部分はシングルスレッドになっちゃうよね。
#確かに>REPL
#そうなんですよね
#今までS式の発想しかなかった。
#ふむー、するとevalの部分もうまい具合にコルーチン化するか、あるいはスレッドプールと組み合わせられるようになってると
#だから、本格的なものを作ろうとすると、evalの部分まで多重化する必要が出てくるのだけど
#request-reply型のサービスがみんなlistenerでサポートできちゃうのかな。
#じゃないかな、と思ってます
#パフォーマンスとか並列実行性をサポートするとなると、listenerの枠組みからはみ出るかもしれませんが
#いや、これは方向としてとっても筋がいいと思う。
#request/reply handlingのところがフレームワークやアプリケーションで書かれていると、テストする時にどうしてもフレームワークやアプリケーションを全部ロードしないとならないってことになりがちで、腰が重くなるなあと感じてたんですよ。
#もちろん綺麗に分離して書いとけばいいんだけど。さくっと書くとついつい密結合になっちゃう。
#標準モジュールでそこが綺麗に分離されて共通部分がサポートされてると、テストはevalの部分に集中できる
#listenerはモデルとしてシンプルなんで、裏で性能のためにごちゃごちゃやったとしても、開発者の精神的な「重さ」が無いんじゃないか、という気がする。
#その手のアプリを書いてると、read-printの部分は毎回同じようなものを書くじゃないですか
#そうそう。
#chatonでもなんだか似たようなことやってるなと思いながら書いてた。
#性能と手軽さのバランスが難しそうだけど、とっつきとしてはやりやすいんじゃないかと思ってます >listener
##Perl に POE っていうモジュールがあるんですが、
#これは、非同期のネットワーク通信のフレームワークで、
#(び)さんがいっているのにもしかしたらちかいかも。
#アプリケーションをイベントドリブンでかける。
#POE 自体は、ネットワークとは関係ないかな。汎用のイベント駆動フレームワーク。
##ぼくはつかったことないんですけど。
#RubyにもFiberとの連携で同じようなことをするライブラリがあったと思う(名前忘れた)
#あと、PythonのTwistedにもあったような
#でも、そこまで大規模なものが欲しいわけじゃないのだよね
#フレームワークを書こうとすると大掛かりになっちゃうから
#listenerに毛を生やすところからはじめてけばいいと私も思う。
#ただ、現状のlistnerはS式縛りになってるんですね
#だから、Kahuaに使うのは問題ないけど、一般的なrequest/responseアプリに使うには、complete-sexp? をカスタマイズ可能にしなきゃいけないのかな
#ですね。
#それと書き込みのバッファリングをするところまでやったら骨組みができるから、そこからどうチューニングしていくかを考えればいいんじゃないかな
#とlistener-read-handlerの実装を見ながら考えております
#スクリプトを書いて、Lingrの過去ログのニックネームが取得できたっぽいです。
#sxpathをもっと使いこなせるようになりたい...
#wgetで取得したHTMLからhtmlpragでS式に変換して sxpathで抜き出ししました。
#といっても、sxpathだけで綺麗に書けたわけではなく...
#後日、ニックネームのデータもあわせて公開します。
#乙です>kiyoka
#wgetしたHTMLを公開するというのはどうだろう。
#wgetしたHTMLってどう見えるんでしょうか。まだ試してみてないです。CSSとかアイコン画像とかどんな風になるんだろう。
#どうやら、wgetしたhtml中のURLはlingr.com上のURLになってますね。wgetのオプションでローカルに置換できるかな。
#今私がwgetしたデータだとlingr.comがシャットダウンしてしまったら、レイアウトがくずれたりアイコンが出なくなったりしますねぇ。
#wgetのオプションにはURL置換機能は無さそうですね。
#あっ、--convert-links これか。
#そんなオプションが>wget
#--convert-links オプション付けて取得したデータと、付けないで取得したデータをdiff取ったが、URLの置換は行われてなかった。
#wgetって、HTMLの改ざんなんか本当にするのかなぁ。
##これでやってみたけど、置換が行われないよ。
#まあいいや。OldTypeに置換してみるのも一興かな。
#cssやjsは変換してくれないみたい>--convert-links
#そうですね。wgetごときに完璧なHTMLパースを求めてはだめかな。
#Firefoxの「別名でページほ保存」というメニューでは完璧にローカル化してくれるんだけど、リンクのクローリングはしてくれない。
#その両方を満たすソフトは、ありそうな気もしますね。
#Spydering Hacks?
#Spideringか
##ScrapBookというプラグインがあるようです。
#掘り下げ取り込み機能という、直訳的な名前の機能があるようですね。
#いま、ScrapBookを試しに使ってみてます。使い物になればいいな。
#ScrapBookでうまく全データ取れたっぽいです。
#listener の input-port に ssax:xml->sxml を噛ますと XML が読めるようになったりします?
#ぼくがいまつくってる webchat も、あとで下層の CGI 部分を切り離して、別の入出力モジュールに取り替えられるようにしようと思っているんですが、
#そこが listener に
#置き換えられると楽かも。
#それだとXMLが完結するまでポートから読み出せない=readが帰って来ないので、listenerのメリットが半減するんじゃないかなあ
#ああ、そこでブロックしちゃうんですね。
#じゃあ読めるだけ読んで、整形式の XML かどうかを確かめて、整形式じゃなければ、バッファにためるっていうのを作ればいいのかな。
#むかしそういうのを C++ で作ったことがありますが、めんどくさかった……。
#あ、昔作ったのは Flash の XMLSocket 用で、これはなぜか XML 文書の最後をヌル終端するという決まりがあったので、比較的やりやすかったんでした。