うう、こまったな、無性に Ruby のコードが書きたくなってきた。 こんなことをやっている余裕はまだないのだが……
[ruby-core:04345] [BUG?] Ripper
もちろん、バグではない。
しかしこれは、どう答えたものかなあ。 この人が求めているものを簡単に実現する方法はまだ存在しないのだが。 いや、tstring_content だけを取り出せばいいのなら簡単だけど、 それだと他の (ヒアドキュメントじゃない) 文字列も拾ってしまう。
まず前提として、トークンはこうなっている。
~ % ruby -rpp -rripper -e 'pp Ripper.scan(%(<<HERE\nstring\nHERE))' [[[1, 0], :on_heredoc_beg, "<<HERE"], [[1, 6], :on_nl, "\n"], [[2, 0], :on_tstring_content, "string\n"], [[3, 0], :on_heredoc_end, "HERE"]]
heredoc_beg と heredoc_end の間にある tstring_content だけを取りたいというのが求める解だろう。 正規表現マッチみたいなことができればいいわけだよな。
pattern = 'heredoc nl $(tstring_content*) heredoc_end'
と、いう感じにパターンを記述し、
Ripper.slice("<<HERE\nstring\nHERE", pattern, 1)
てな感じで $(...) にマッチする部分を取れる、というのはどうだろう。 をー、なんかいい感じがしてきたぜ。
実装はどうすっか。自分でエンジンを書くのはだるいな。
よし、考えついたぞ。 パターンは正規表現にコンパイルし、 対象は文字列にコンパイルして、普通に正規表現マッチを行う。 で、インデックスで両者の対応を取ればよい。
あー、実装したくなってきたけど、がまんしよう。
(01:43)
おれは誘惑に弱すぎると思った。
~/c/ruby/ext/ripper % ruby -I./lib -rripper -e ' p Ripper.slice(%Q(<<HERE\nstring\nHERE), "heredoc_beg nl $(tstring_content *) heredoc_end", 1) ' "string\n"
意図していなかったが、こんなこともできるようだ。
~/c/ruby/ext/ripper % ruby -I./lib -rripper -e ' p Ripper.slice(%(<<HERE\nstring\#{nil}\nHERE), "heredoc_beg nl $(.*?) heredoc_end", 1) ' "string\#{nil}\n"
これって、もしかしてすごく便利なのでは……
(02:40)
なんと pure Ruby でここまで goto らしく! 画面右側は隠して御覧ください。
require 'goto' __{ _ :hata1 do cls goto :hata3 end _ :hata2 do mes "はーい、こんにちは" end _ :hata3 do mes "旗を立ててみるテストです" stop end}
……だめだろーなー……。
ちなみに goto.rb はこんなの。
class GotoEnviron def initialize @blocks = nil @table = {} end def push_block(flag, block) b = Block.new(block) if @blocks @blocks.last.next = b else @blocks = b end @table[flag] = b end def exec b = @blocks while true target = catch(:__goto_environ_jump) { while b b.call b = b.next end return } break unless target raise ArgumentError, "no such flag: #{target}" unless @table[target] b = @table[target] end end def goto(target) throw :__goto_environ_jump, target end class Block def initialize(block) @block = block @next = nil end def call @block.call end attr_accessor :next def last b = self while b.next b = b.next end b end end end def __ @env = GotoEnviron.new yield @env.exec end def _(flag, &block) @env.push_block flag, block end def goto(target) @env.goto target end
(21:36)
結城さんの新作は『プログラマの数学』らしい。
やばい、すげえ面白そうだ。 秘かに数学コンプレックスを持つ文系プログラマとしてはこれは買うしかない。
もしかして Haskell をさわってたのもこの関連なのかなあ。
(17:24)
http://dgames.jp/dan/?date=20050203#p01
> goto が何箇所かで話題になっていたりして > このサイトにも多少の影響力あり? > てゆーか自意識過剰?
いえ、dan さんのとこ見て書きました。 書き終わったときにすでに Mozilla のタブを閉じてたから 面倒くさくて URL を張らなかっただけです。
(18:30)
http://yowaken.dip.jp/tdiary/20050203.html#p02 より、 なんだけど、最初の派生元は 2ch だろうか。
ぼくも IO#<< は使いません。 ついでに言えば Array#<< も String#<< も使いません。 だって Array だと push なのに String だと concat だから、 つい Array#concat のつもりで << を使ってしまうんです。
(18:56)
光ファイバー回線導入工事のため、 2 月 15 日 (火) に loveruby.net の全サーバが停止します。 あらかじめ御了承ください。
(19:09)
クロスプラットフォーム萌えなわたしとしては Solaris 10 超期待ですよ。特に AMD64 対応がいい。 dual Opteron で Solaris 10 入れてメインマシンにしちゃえー という声がどこからか聞こえてくるほどです。 もう皮算用が止まらんね。
(19:46)
Array#<< も String#<< も使いません。
とは書いたものの、ちょっと grep してみると、 String#<< は意外と使っていた。 それに対し Array#<< は見付からなかった。 やはり Array#push と concat が混乱するのが嫌みたいだな。
(22:21)
srcdir 以外で HEAD をビルドしたら tk で止まった。 報告しようかと思ったが、中田さんのパッチが入れば なおるようなので、それまで待つことにする。
(02:06)
ぐぁ、昼のコミットで通るようになっただろーと思ったら、 テストの変更だけコミットしわすれてた……。
コミットしたら Tru64UNIX 5.1B でも 1F になった (iconv に "euc-jp" がないため)。
(02:44)
そういえば、ずっと無視してきたんだけど、 これはどうするべきなんだろう。
tunami:~/src/ruby % /usr/local/pkg/ruby-ccc/bin/ruby test/runner.rb test/xsd/test_noencoding.rb Loaded suite test_noencoding.rb Started E Finished in 0.017578 seconds. 1) Error: test_wsdl(XSD::TestEmptyCharset): Iconv::InvalidEncoding: invalid encoding ("euc-jp", "utf-8") (eval):6:in `iconv' (eval):6:in `encode' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/rexml/source.rb:41:in `encoding=' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/rexml/parsers/baseparser.rb:202:in `pull' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/rexml/parsers/streamparser.rb:16:in `parse' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/rexml/document.rb:171:in `parse_stream' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/xsd/xmlparser/rexmlparser.rb:27:in `do_parse' /usr/local/pkg/ruby-ccc/lib/ruby/1.9/wsdl/xmlSchema/parser.rb:60:in `parse' ./test/xsd/test_noencoding.rb:15:in `test_wsdl' 1 tests, 0 assertions, 0 failures, 1 errors
まず、Tru64UNIX みたいなマイナープラットフォームを サポートする必要があるかという問題がある。 主要プラットフォームでは iconv 自体が "EUC-JP" をサポートしているし、 サポートするプラットフォームは増えていくだろう。 だからこれは無視してもいいという考えもありうる。
第二に、どこで対処すべきかがよくわからない。 iconv か、rexml か、xsd か。 どこで対処するのもそれなりに理がありそうな気がする。
ちなみに EUC-JP のコーデック自体は用意されているのだが、 名前が "eucJP" になっている。 なので、どこで対処するにしても変更自体は簡単なはずである。
(02:51)
http://nais.to/~yto/clog/2005-01-18-3.html
遅ればせながら俺もやったよ日記マイニング!
~/tmp/tdiary % /usr/pkg/sufary-2.3.8/bin/sang -t 100 -n 10 out 138 ということ 140 とりあえず 110 インストー 107 コンパイル 106 ライブラリ 101 ンストール
とりあえずライブラリのコンパイルとインストールばかりしていたということがわかる。
~/tmp/tdiary % /usr/pkg/sufary-2.3.8/bin/sang -t 50 -n 12 out 58 ―――――― 60 うな気がする 53 かもしれない 52 じゃないです 52 たんですが、 53 と思います。 57 ような気がす 101 インストール 66 オブジェクト 85 ソースコード 89 プログラミン 89 ログラミング
インストールばかりしてたような気がするのだけど、 実はソースコードばかり書いていたのかもしれないと思います。 嘘じゃないです。 オブジェクト指向プログラミングキタ――――――!
(02:25)
■
sugi [refe 0.8.0 でデータを更新しようとしたら、
% mkrefe_rubyrefm man-rd-ja/*.rd
/usr/local/lib/ruby/site_ruby/1.8/refe/rubyrefmparser.rb:180:in `get_method_name': (RuntimeError)
BigDecimal.rd:378: cannot get method name
"--- divmod,quo,modulo,%,remainder\n"
from /usr/local/lib/ruby/site_ruby/1.8/refe/rubyrefmparser.rb:155:in `read_entry'
from /usr/local/lib/ruby/site_ruby/1.8/refe/rubyrefmparser.rb:141:in `register_entry_to'
from /usr/local/lib/ruby/site_ruby/1.8/refe/rubyrefmparser.rb:123:in `parse'
from /usr/local/bin/mkrefe_rubyrefm:60:in `update_database'
from /usr/local/bin/mkrefe_rubyrefm:59:in `open'
from /usr/local/bin/mkrefe_rubyrefm:59:in `update_database'
from /usr/local/bin/mkrefe_rubyrefm:57:in `each'
from /usr/local/bin/mkrefe_rubyrefm:57:in `update_database'
from /usr/local/bin/mkrefe_rubyrefm:49:in `main'
from /usr/local/bin/mkrefe_rubyrefm:122
というエラーになってしまったのですが、これはデータが悪いのでしょうか?]
■
青木 [それは複数に分けて書いてほしいところですねえ。
こんな感じに、
--- div
--- modulo
--- %
エントリを並べて書いておけば ReFe の表示では
一つにまとまります。]
■
sugi [ありがとうございます。
ここは分けることで解決したのですが、他にも
--- CGI#[key]
とか
--- EOC # => 0
みたいに書いてあるところがあったりとか、
いろいろ問題がありそうです。
リファレンスマニュアルをどういう表記にすべきかというのが
分からないので、これらの表記を直していいのか不明です。
(MLに投げた方がいいのかなぁ)
お暇なときにでも、一度見てみていただけませんでしょうか。]
■
sheepman [OpenSSL::ASN1 で --- EOC # => 0 と書いたのは僕です。
--- EOC
0
と書くと定数名と数字との対応が見にくかったので。何か代替案を思い付いたら教えてください。マニュアルの表記法の議論に関しては
http://www.freeml.com/ctrl/html/MLInfoForm/rubyist
だと気兼ねなくできるとおもいます。気が付いた点があったら投稿してください。]
■
青木 [rubyist ML のほうに書いたのを転載します。
「#=>」はサンプルコード中で値を書くときの表記ですし、評価した
値を暗示するので、メソッドリストで使うべきではないと思います。
また、RDoc だとかわたしの使ってるドキュメントフォーマットだと
--- StringScanner#eos? -> bool
という表記がありますが、これは基本的に返り値の値ではなく型を
示すものと認識しています。
また、ReFe などでエントリだけを単独で読んだ場合には
--- EOC #=> 0
のような表記をされると、はっきり言ってわけがわかりません。ReFe
のような自動処理を行ううえでも、RWiki 上で表現を圧縮するよりも
形式が統一されていることが重要だと思います。
以上の三点から、メソッドリストで「#=>」を使うのには反対です。
ReFe でも当面はサポートしません。]
光回線敷設完了。 実効 84Mbps 出てるとかで工事の人もびびってた。
(13:32)
それにしても全然違いがわからない。 ここまで違いがないと悩むぞ。 ルータがボトルネックになってるのかなあ。
http://jp.rubyist.net/magazine/?0005
お、出ましたねー。 今回は自分の原稿とテストで死んでたから何もできなかったな。
今回はインタビューがえらい面白い。 このインタビューはこれまで外れがなくおもしろいけど、今回は特に面白い。
記事の中だと、ゲームがらみってことで RGSS にはかなり興味がある。 ちょっと欲しくなった。しかし最大の問題は、 俺は「Ruby が普通に使える」なんてくらいじゃ全然興味がわかないことだなあ。 Ruby を使うだけだったらコンパイルすればいいじゃん。 したがってこの製品で一番重要なのはライブラリと素材だと思うのだが、 今回の記事はそういう紹介が少ない。 RPG ツクールのサイトでは逆にレベルが低すぎて API がちゃんと載ってないからだめだ。 例えばどんなクラスがあるかって表だけでもあるとよかったと思うんだけどな。
次。CGIKit はちょっと気になっていた。 でも俺は RDB 嫌いなので Tapkit はどうでもいい。さっくり無視。 ……とか適当な読みかたをしたら全然わからんかった。 誰か RDB が必要ないウェブアプリケーションフレームワーク作ってくれよう。 Rails も RDB ありきでセットアップがめんどくせーんだよ!
つーことで lily に興味を持ってみる。 いや、lily はウェブアプリケーションフレームワークじゃないと思うが それは置いといて、そういう文脈で読むことを試みる。
……うーん、だめだ、やっぱ文章読んでるだけじゃわからん。 俺には勘とソースコードだけで動かすほうが向いてる。 (つーことでダウンロード中)
それはそうと俺思うんだけどね、 もっと構造が簡単な個人用 CMS が欲しいんだよ。 ruby があればファイル一個置くだけでいきなり動かせて、 FTP もエディタも使わずにサイト構築できるようなやつ。 んで日記と掲示板と Wiki と絵チャとギャラリーとカウンターが使えて、 できればコンテンツは自動的にバージョン管理システムの管理下に置きたい。 普通のページは HTML だけじゃなくて RD like なシンタックスとか Wiki シンタックスとか使えるといいな。 モノは Ruby でも全部揃ってるはずなので、あとはつなげばよいと思うのだが。
んで、先にるびまの続きを読むと、Win32utils が地味に便利そうね。 クリップボードとか Windows サービスとか。 ファイバまで使ってるのは驚きだ。たぶんうまくいかんだろうけど。
とりあえず、アーカイブを展開したら lily-X.X.X みたいなディレクトリを作ってほしい気がする。 tDiary もバージョンついてないんだっけ? でも、どーせディレクトリを作っちゃったらどういう名前だって変わらなくね?
あーそうか、ファイル一つと言ってもテーマまでまとめるのは難しいなあ。 「アプリケーション部分はファイル一つ」くらいにすべきか。 設定ファイルも一つだけは分離してもよいことにしよう。
chmod 755 する。出ない。 ああそうか FollowSymLinks と AddHandler が足りんかった。追加。 出た。
出たが……。どうやってエントリを追加すればよいのだろう。 えー、手動でファイル追加するのか。めんどくさい。 カテゴリでディレクトリ分けるのもめんどくさいなあ。 俺カテゴリ嫌いだし。
えー、Wiki スタイルにするのにダウンロードしなくちゃいけないのかー。 だるい (やるけど)。 ああ、tDiary の Wiki スタイル由来なのね。 もしかしてライセンスが違うから別々なのか。
カテゴリを使わないで書くとどうなるんだろ。 ああ、これでも出るのか。カテゴリ面倒だから全部これでいいや。
初エントリ書いた。出た。
ふーむ、日付はどこから来てるんだろう。もしかして st_mtime か。 ……touch しても時刻が変わらない。どこに保存してるんだ。 find で発見。log/.entrydate だな。 最初にファイルを表示したときにここに記録されるのか。
コメントを付けようとするとファイルがないと言われた。なぜだ。
うわ、これは mod_rewrite の「ホームディレクトリで使うとはまる罠」っぽい。 やっぱりそうだ。RewriteRule のターゲットを絶対パスにしたら治った。
コメントも動いた。
と、言いますか、コメントで「--------」だけの行を書くと lily を狂わせられるような気がするのはわたしの気のせいか。
確かに動作は変になるが、それほどおもしろい結果にはならなかった。
Firefox で見るときれいだが w3m で見るとヘッダが邪魔だな。
ま、ファーストコンタクトはこんなもんか。
(21:42)
返事するのをすっかり忘れてました。 ツッコミを再掲すると、
> ■なかだ (2005-02-05 15:23) > > config.charsetを$(srcdir)に置いておくとiconv.rbというラッパーを作ります。 > http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset
config.charset のことは知ってますが、 それで個別に解決「すべきなのか」というところを問うてます。 個別に解決するということは、ライブラリなんかを書く人は 結局それがないことを前提に書かざるを得ないでしょう。 そう決めたならそれでいいんですが、 そう決めてないのであれば日本語関連だけでも エイリアスを用意しちゃえばいいのかなーと。 なにもプラットフォームごとに対応表を用意しなくても、 動的にチェックして定義しちゃえばいいんじゃないかと思うんですよ。
例えばわたしの調査によると EUC-JP の変換表が使いたければ "eucJP" という名前を使うのが一番ポータブルなんですが、 この "eucJP" と "EUC-JP" が異なる変換表に 割り当てられている状況はさすがに考えられません。 だから、"EUC-JP" と "eucJP" は全プラットフォームで同じものと考えて エイリアスを (Ruby 側で) 用意しておけばいいのではないかと思うわけです。 そういう感じの定義方法であればプラットフォームごとに 対応する必要はほとんどないはずなので負担は比較的低いでしょう。
> でもTru64UNIXだとCONFIG["target"]は何?
ベンダがちょっと不確実ですが、恐らく "alphaev6-dec-osf5.1" です。 ruby --version だと [alphaev6-osf5.1] なんで。
(21:59)
暇になったとたん何もやる気が起きない。 とりあえず今日はもう寝よう。
それに暇とは言っても本のまえがきとを書くとか 練習問題の答えを書くとかの残務は結構あるんだよなー。 あー……やる気でねえー。
(22:11)
■ moriq [RailsはRDBなくても使えますよ。ActionPackのsampleはActiveRecord使ってないし。]
■ suzuki [CGIKitもRDB必須ではないですよ。両方組み合わせて使えるのを想定してはいますが、基本的にそれぞれ独立してます。]
■
青木 [すばやい御指摘ありがとうございます。
んー、でも、それは「なくても残りの部分が動く」というだけで、
RDB を捨てちゃったら永続データをカバーするライブラリが存在
しなくなるわけですよね。それだとあまり意味がないと思います。
例えば RDB じゃなくて簡易 OODB が使えるとか、任意のオブジェクト
をファイルシステムに保存するフレームワークが用意されているとか、
何か代替物がないと、単に「モデルをカバーしないフレームワーク」
になってしまいませんか。]
■ arton [いや、ファイバは盲点だった。ネイティブスレッドと違って問題ないかも知れない。って言うか閑なら試したいな(つまり閑じゃないから試せない)。]
■ suzuki [CGIKitはWebインターフェースのみをカバーするのが目的で、「DB部分はお好きなライブラリをどうぞ」という指針なので、「モデルをカバーしないフレームワーク」ですね。WebインターフェースとDBモデルの依存度は低い(今のところほぼない)です。]
■
青木 [む、そういうものですか。Rails はちょっとだけ
試したことがあるんですが CGIKit はソースツリーを
眺めただけなので、今度試してみようと思います。]
■
青木 [ファイバって「Windowsでのユーザスレッド実装」くらいの
イメージしかなかったんですが、うまくいくんですか。
"Advanced Windows" でも読んで勉強しとこ……。]
■
arton [今、ちょっと調べたけど僕が大きく勘違いしてるかも知れない。
着眼点が良いなと思ったのは、ファイバそのものは単一のスレッドで動作できるからネイティブスレッドで問題となる異なるスレッドのjumpバッファの戻しが原因の異常状態がなくなるんじゃないかと思ったという点と、GCで問題となるスタックトップの位置の変化が起きないという点の2つなんだけど、最初の点についてはファイバ単位にWindowsも同様な管理をするはずだからやっぱり異常な状態(異なるファイバのスタックの戻し)になってしまうかも(というかrubyのスレッドそのものがファイバなわけだし=余りメリットは無いかも)。]
■
noritada [あのー……またまたしょうもないツッコミですみませんが、
一応、タイトルが Rubyist Ma*n*agine に (ry]
■
サイロス誠 [初めまして。
評価ありがとうございます。
今回の記事は、いきなり内部まで突っ込むよりも、とりあず動作を分かり易く紹介して、そののちインタフェースにも手を出そうかというスタンスで考えております。
次回執筆いたしましたら、よろしくお願いします。]
■
青木 [ううっ、manage → magazine 修正しました。
最近 typo 製造機と化してるなあ。]
■
青木 [> RGSS
なるほど、続きがすでに構想されているのですね。
楽しみに待ってます。]
なぜか AIX で ruby のコンパイルを始めてみた。手強い。
[環境]
[参考資料]
まず何も考えずに configure; make してみると、 miniruby のリンクで止まる。-brtl がよくないらしい。 これはリンカ (/usr/ccs/bin/ld) のオプションなので、 gcc を使う場合は -Wl,-brtl にする必要がある。
それはともあれ、とりあえず先に進めるために -brtl を取ってみると miniruby は作れて動くようになる。
~/obj/ruby $ make miniruby gcc main.o libruby-static.a -ldl -lcrypt -lm -o miniruby -g -O2 ~/obj/ruby $ ./miniruby -v -e 'puts "OK"' ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] OK
……が、拡張ライブラリがコンパイルできない。
compiling bigdecimal gcc -g -O2 -I. -I../.. -I../../../../src/ruby -I../../../../src/ruby/ext/bigdecimal -c ../../../../src/ruby/ext/bigdecimal/bigdecimal.c In file included from ../../../../src/ruby/ruby.h:21, from ../../../../src/ruby/ext/bigdecimal/bigdecimal.c:23: ../../config.h:7:1: warning: "_ALL_SOURCE" redefined In file included from /opt/freeware/lib/gcc-lib/powerpc-ibm-aix5.1.0.0/3.3.2/include/ctype.h:32, from ../../../../src/ruby/ext/bigdecimal/bigdecimal.c:16: /usr/include/standards.h:99:1: warning: this is the location of the previous definition /usr/ccs/bin/ld -brtl -eInit_bigdecimal -bI:../../ruby.imp -bM:SRE -T512 -H512 -L"../.." -o ../../.ext/rs6000-aix5.1.0.0/bigdecimal.so bigdecimal.o -ldl -lcrypt -lm -lc ld: 0706-003 インポート・ファイルが見つからないか、読み取れません: ../../ruby.imp ld:accessx(): このパス名のファイルまたはディレクトリは存在しません。 make: 1254-004 最後のコマンドからのエラー・コードは 255 です。 停止します。 make: 1254-004 最後のコマンドからのエラー・コードは 1 です。 停止します。
いろいろ調べた結果、make ruby.imp でエクスポートライブラリを作っておく必要があるとわかった。 めんどくさい。
※ さらに後の調べによって、--enable-shared のときは自動的に作成されることが判明
ruby.imp を作っておくとビルドは問題なく最後まで行くようになったが、 今度は拡張ライブラリがロードできない。
~/obj/ruby $ sudo make install 略 ~/obj/ruby $ /usr/local/pkg/ruby/bin/ruby --version ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] ~/obj/ruby $ /usr/local/pkg/ruby/bin/ruby -rbigdecimal -e0 ./bigdecimal.so: load failed - ./bigdecimal.so (LoadError)
さてどーするかな。
まず、小さいアプリケーションでもって、 dlopen を使ったライブラリルーチンの正しい呼びかたを確認してみる。 構成はできるだけ ruby に似せて次のようにする。
このとき次のようにすると動作するライブラリが作れる。
~/c/test/c/shlib $ make gcc -c -Wall main.c -o main.o gcc -c -Wall libruby.c -o libruby.o gcc -shared -Wl,-G libruby.o -o libruby.so gcc -c -Wall extlib.c -o extlib.o gcc -shared -Wl,-G -Wl,-rtllib extlib.o -L. -lruby -o extlib.so ld: 0711-224 警告: シンボル ._GLOBAL__DI が重複しています。 ld: 0711-224 警告: シンボル ._GLOBAL__DD が重複しています。 ld: 0711-224 警告: シンボル _GLOBAL__DI が重複しています。 ld: 0711-224 警告: シンボル _GLOBAL__DD が重複しています。 ld: 0711-345 -bloadmap または -bnoquiet オプションを使用して、詳細な情報を得てください。 gcc main.o -Wl,-brtl -L. -lruby -o ruby ターゲット "all" は最新のものです。 ~/c/test/c/shlib $ ./ruby result=25
_GLOBAL__DI, _GLOBAL__DD は C++ のコンストラクタとデストラクタらしい。 無視しておこう。
ポイントは 4 点ある。
拡張ライブラリに libruby をリンクするのは、 rb_xxx_xxxx() をリンクするため。 どうも AIX では単純に dlopen するだけだと 拡張ライブラリ → ruby のシンボル解決ができないっぽい。 だから libruby を独立させて、 コンパイル時にシンボルを解決してしまう必要がある。
また現在の ruby は拡張ライブラリを作るときに ld -eInit_xxxx -bM:SRE -T512 -H512 というフラグを使っているが、 これは必要ないようだ。-G -brtllib だけ付けておけばよい。 man ld には次のようにある。
-G Produces a shared object enabled for use with the run-time linker. The -G flag is equivalent to specifying the erok, rtl, nortllib, nosymbolic, noautoexp, and M:SRE options with the -b flag. Subsequent options can override these options. This flag only applies to AIX 4.2 or later.
共有ライブラリを作るときに必要なのは -bM:SRE オプションなんだが、 これは -G では暗黙のうちに指定される。 また -berok により未定義シンボルが許可されるので、 明示的にシンボルをインポートする必要はない (つまり ruby.imp とかのあたりがすべて必要なくなる)。
念のため他のフラグも見ておく。
-brtl はオブジェクトファイルにライブラリの名前を埋め込むオプションで、 共有ライブラリにリンクするオブジェクトファイルをビルドするときに必要。 また -l オプションのライブラリを探すとき、*.a 以外に *.so も見るようになる。 -G を付けると暗黙のうちに -brtl もセットされる。
ちなみに AIX では共有ライブラリも *.a という名前を持つが、 中身は *.so と一緒 (ECOFF オブジェクトファイル) である。 さらに言えば共有ライブラリはバージョニングされない。 このへんは Tru64UNIX と似ているようだ。
-brtllib は librtl をリンクするフラグで、 dlopen でロードされるライブラリに必要。 -G は暗黙のうちに -bnortllib をセットするので、 -brtllib を明示的に追加する必要がある。
以上の知見をもとに Makefile と config.status を 書き換えまくってみたところ、ビルドまではうまくいった。 しかし拡張ライブラリをロードすると失敗する。
あれ?
あれれ?
……dlopen が使われてないじゃねえかー! これが原因か! dln.c を書き換えて #ifdef AIX を抹殺する。
~/obj/ruby-shared $ ruby -v -rbigdecimal -e 'p $"' ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] ["bigdecimal.so"]
勝利!
ん? そういえば rpath を設定してないのになんで実行できるんだろ。 もしかしてカレントディレクトリに libruby.so があるからか。 移動するとどうなる?
~/obj/ruby-shared $ cd ~ $ ruby --version exec(): 0509-036 以下のエラーのためにプログラム ruby をロードできません: 0509-150 従属モジュール libruby.so をロードできませんでした。 0509-022 モジュール libruby.so をロードできません。 0509-026 システム・エラー: このパス名のファイルまたはディレクトリは存在しません。
だめじゃん……。
どーすればいいんだろう。 ld -blibpath:$prefix/lib:/usr/lib かな?
~/obj/ruby-shared $ gcc -Wl,-brtl -Wl,-blibpath:/usr/local/pkg/ruby/lib:/usr/lib main.o -L. -lruby -ldl -lcrypt -lm -lc -o ruby ~/obj/ruby-shared $ sudo cp ruby /usr/local/pkg/ruby/bin/ ~/obj/ruby-shared $ cd ~ $ ruby --version ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0]
うまくいったもよう。確認。
~ $ dump -H /usr/local/pkg/ruby/bin/ruby /usr/local/pkg/ruby/bin/ruby: ***Loader Section*** Loader Header Information VERSION# #SYMtableENT #RELOCent LENidSTR 0x00000001 0x00000015 0x00000071 0x0000004e #IMPfilID OFFidSTR LENstrTBL OFFstrTBL 0x00000004 0x00000764 0x0000005d 0x000007b2 ***Import File Strings*** INDEX PATH BASE MEMBER 0 /usr/local/pkg/ruby/lib:/usr/lib 1 libruby.so 2 libc.a shr.o 3 librtl.a shr.o
ちゃんとセットされているようだ。
さて、パッチをどうするかな。 よーするに、パラメータをこうすりゃいいはずなんだが。
LDSHARED = gcc -shared LDFLAGS = -Wl,-brtl -Wl,-blibpath:$(prefix)/lib:/usr/lib -L. -lruby DLDFLAGS = -Wl,-G -Wl,-brtllib $(EXTLDFLAGS) XLDFLAGS = $(EXTLDFLAGS) EXTLDFLAGS = LIBRUBYARG = -L$(topdir) -lruby
あと dln.c の AIX 独自コードを捨てて dlopen にする。 これで全部通るはずだ。
問題は古いバージョンの AIX だなあ。 man を見ると、4.2 より前とそれ以降でかなり劇的に変わっているようだ。 4.1 以前は無視、てことならば、 上記のように変更してしまえばすべてカタが付く。 無視しないのなら、これまでのパラメータを残しつつ変更する必要がある。
(07:05)
そーいえば socket がコンパイルされてなかった。 mkmf.log を見る限り、IPv6 がらみの getaddrinfo がだめみたいだ。 てっとりばやく --enable-wide-getaddrinfo で通す。
~/obj/ruby-shared/ext/socket $ ruby ../../../../src/ruby/ext/socket/extconf.rb --enable-wide-getaddrinfo 略 ~/obj/ruby-shared/ext/socket $ make 略 ~/obj/ruby-shared/ext/socket $ ruby -rsocket -e ' s = TCPSocket.open("harmony", 80) s.puts "GET / HTTP/1.0" s.puts puts s.read s.close ' HTTP/1.1 200 OK Date: Wed, 16 Feb 2005 22:13:40 GMT Server: Apache/1.3.28 (Unix) mod_fastcgi/2.4.2 mod_ruby/1.0.7 Ruby/1.9.0 mod_ssl/2.8.15 OpenSSL/0.9.7b Last-Modified: Fri, 05 Mar 2004 15:40:57 GMT ETag: "22529-ff-40489f89" Accept-Ranges: bytes Content-Length: 255 Connection: close Content-Type: text/html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> <title>harmony</title> </head> <body> <h1>harmony</h1> <p>Apache working on harmony</p> </body> </html>
解決。
(07:17)
AIX 用のエクスポートファイルを作る方法。
ruby は nm を使っているが、 dump を使ってもよいらしい。
# mkexp.rb table = {} `dump -g #{ARGV[0]}`.each do |line| next unless /\A\s*\d/ =~ line idx, name = line.split table[name.sub(/\A\./, '')] = true end puts table.keys.sort
(07:22)
x86 の 64 ビット拡張で一番嬉しいのって、 実は 64 ビットになったことじゃなくて 汎用レジスタが 16 本になったってことじゃないかと思うんだけど、どうよ。 すでに内部でレジスタリネーミングとかやってるからあんまり影響ないのかな。
(21:27)
「なでし・こむ」か。 とりあえず「む」の消費方法を考えるべきだな。
つか
> なでしこ違いで来てしまった人はこちらへ(笑)。
あっちはカタカナでしょ!
(00:04)
何するか悩んだらとりあえず make test-all しておくらしい。
drb, rinda, soap4r, webrick が全滅。 エラーを見ると、iconv か getaddrinfo を使うものがすべて失敗していた。 逆に言うとそれ以外はすべて成功しているわけで、 思ったよりちゃんと動くという印象を受けた。 もうちょっと詰めていけば問題なく使えそうだ。
とりあえず getaddrinfo のほうを見てみよう。
~/c/bin $ ruby -v getaddrinfo.rb localhost ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] AF_INET 127.0.0.1 0 IP ~/c/bin $ ruby -v getaddrinfo.rb rs7012 ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] AF_INET 192.168.1.43 0 IP
ええ? 何これ。 Linux だとこんな感じになるんだけどな。
~/c/bin % ruby -v getaddrinfo.rb localhost ruby 1.9.0 (2005-02-23) [i686-linux] AF_INET 127.0.0.1 STREAM TCP AF_INET 127.0.0.1 DGRAM UDP AF_INET 127.0.0.1 RAW IP
getnameinfo はさらに酷くて、何も通らない。
~/c/bin $ ruby -v getnameinfo.rb 127.0.0.1 ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] ./getnameinfo.rb:12:in `getnameinfo': getnameinfo: Host not found (SocketError) from ./getnameinfo.rb:12:in `getnameinfo' from ./getnameinfo.rb:7:in `main' from ./getnameinfo.rb:15 ~/c/bin $ ruby -v getnameinfo.rb 192.168.1.43 ruby 1.9.0 (2005-02-14) [rs6000-aix5.1.0.0] getnameinfo.rb:12:in `getnameinfo': getnameinfo: Host not found (SocketError) from getnameinfo.rb:12:in `getnameinfo' from getnameinfo.rb:7:in `main' from getnameinfo.rb:15
何がどうなってるんだ。
いろいろ試した結果、IPv6 関係がダメダメなことがわかった。 --disable-ipv6 --with-lookup-order-hack=INET でようやく成功。
~ $ iconv -f us-ascii -t us-ascii iconv: 0791-004 コンバータがオープンできません ~ $ iconv -f US-ASCII -t US-ASCII iconv: 0791-004 コンバータがオープンできません ~ $ iconv -f ISO-8859 -t ISO-8859 iconv: 0791-004 コンバータがオープンできません ~ $ iconv -f ISO8859 -t ISO8859 iconv: 0791-004 コンバータがオープンできません ~ $ iconv -f ISO8859-1 -t ISO8859-1 ^C ~ $ iconv -f UTF-8 -t UTF-8 ^C ~ $ iconv -f eucJP -t eucJP iconv: 0791-004 コンバータがオープンできません
ついに eucJP もないプラットフォームを見付けてしまったか……。 でも ISO8859-1 とか UTF-8 はあるらしいことがわかる。
一覧が欲しいなあ。コンバータはどこにあるんだろ。 さんざん探した挙句、/usr/lib/nls/loc/iconv で発見した。
$ command ls /usr/lib/nls/loc/iconv | ruby -e 'ARGF.each{|s| puts s.strip.split("_") }' | sort -u 64 ASCII-GR CNS11643.1986-1 CNS11643.1986-2 Conv GB18030 GBK IBM-1027 IBM-1046 IBM-1124 IBM-1129 IBM-1252 IBM-290 IBM-300 IBM-850 IBM-856 IBM-921 IBM-922 IBM-930 IBM-930-DOS IBM-932 IBM-939 IBM-939-DOS IBM-943 IBM-eucCN IBM-eucJP IBM-eucKR IBM-eucTW IBM-sbdTW IBM-udcJP IBM-udcJP-GL IBM-udcJP-GR IBM-udcTW ISCII.1991 ISO8859-1 ISO8859-1-GL ISO8859-1-GR ISO8859-15 ISO8859-15-GL ISO8859-15-GR ISO8859-2 ISO8859-2-GL ISO8859-2-GR ISO8859-3 ISO8859-3-GL ISO8859-3-GR ISO8859-4 ISO8859-4-GL ISO8859-4-GR ISO8859-5 ISO8859-5-GL ISO8859-5-GR ISO8859-6 ISO8859-6-GL ISO8859-6-GR ISO8859-7 ISO8859-7-GL ISO8859-7-GR ISO8859-8 ISO8859-8-GL ISO8859-8-GR ISO8859-9 ISO8859-9-GL ISO8859-9-GR JISX0201.1976-0 JISX0201.1976-GL JISX0201.1976-GR JISX0208.1978-GL JISX0208.1978-GR JISX0208.1983-0 JISX0208.1983-GL JISX0208.1983-GR KSC5601.1987-0 TIS-620 UCS UCS-2 UTF-8 Universal big5 ct fold7 fold8 uucode
EUC-JP は IBM-eucJP らしい。こんなの予想できるかっ。 で IBM-932 が shift_jis (というか CP932) のようだ。 とりあえず、エンコーディング名の差を吸収するラッパーをインストールしておく。
これでかなり通るようになったけど、 まだいくつか失敗する。まず drb で一つ。
~/src/ruby $ ruby test/runner.rb test/drb Loaded suite drb Started ...............................E................................................... Finished in 32.556596 seconds. 1) Error: test_10_yield_undumped(TestDRbCore): NoMethodError: undefined method `unpack' for -279519369:Fixnum (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:569:in `load' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:602:in `recv_request' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:899:in `recv_request' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1495:in `init_with_client' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1507:in `setup_message' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1459:in `perform' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1554:in `main_loop' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1550:in `loop' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1550:in `main_loop' (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1546 (druby://rs7012:32900) /usr/local/pkg/ruby/lib/ruby/1.9/drb/drb.rb:1546 (druby://localhost:32973) /usr/local/pkg/ruby/lib/ruby/1.9/drb/invokemethod.rb:10:in `block_yield' (druby://localhost:32973) /usr/local/pkg/ruby/lib/ruby/1.9/drb/invokemethod.rb:17:in `perform_with_block' (druby://localhost:32973) /usr/local/pkg/ruby/lib/ruby/1.9/drb/invokemethod.rb:14:in `each' /home/aamine/src/ruby/test/drb/drbtest.rb:234:in `test_10_yield_undumped' 83 tests, 401 assertions, 0 failures, 1 errors
soap でも一つ。
~/src/ruby $ ruby test/runner.rb test/soap Loaded suite soap Started ......................................................E.................................................................. Finished in 83.757822 seconds. 1) Error: test_success_mu(SOAP::Header::TestAuthHeader): XSD::NS::FormatError: Unknown namespace qualifier: env /usr/local/pkg/ruby/lib/ruby/1.9/xsd/ns.rb:115:in `parse_local' /usr/local/pkg/ruby/lib/ruby/1.9/soap/encodingstyle/soapHandler.rb:543:in `decode_attrs' /usr/local/pkg/ruby/lib/ruby/1.9/soap/encodingstyle/soapHandler.rb:505:in `each' /usr/local/pkg/ruby/lib/ruby/1.9/soap/encodingstyle/soapHandler.rb:505:in `decode_attrs' /usr/local/pkg/ruby/lib/ruby/1.9/soap/encodingstyle/soapHandler.rb:162:in `decode_tag' /usr/local/pkg/ruby/lib/ruby/1.9/soap/parser.rb:180:in `decode_tag' /usr/local/pkg/ruby/lib/ruby/1.9/soap/parser.rb:128:in `start_element' /usr/local/pkg/ruby/lib/ruby/1.9/xsd/xmlparser/parser.rb:67:in `start_element' /usr/local/pkg/ruby/lib/ruby/1.9/xsd/xmlparser/rexmlparser.rb:34:in `tag_start' /usr/local/pkg/ruby/lib/ruby/1.9/rexml/parsers/streamparser.rb:24:in `parse' /usr/local/pkg/ruby/lib/ruby/1.9/rexml/document.rb:171:in `parse_stream' /usr/local/pkg/ruby/lib/ruby/1.9/xsd/xmlparser/rexmlparser.rb:27:in `do_parse' /usr/local/pkg/ruby/lib/ruby/1.9/soap/parser.rb:90:in `parse' /usr/local/pkg/ruby/lib/ruby/1.9/soap/processor.rb:39:in `unmarshal' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/router.rb:156:in `unmarshal' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/router.rb:76:in `route' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/soaplet.rb:108:in `do_POST' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/soaplet.rb:103:in `with_headerhandler' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/soaplet.rb:103:in `do_POST' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/httpservlet/abstract.rb:35:in `__send__' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/httpservlet/abstract.rb:35:in `service' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/httpserver.rb:108:in `service' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/httpserver.rb:69:in `run' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/server.rb:158:in `start_thread' /usr/local/pkg/ruby/lib/ruby/1.9/webrick/server.rb:147 /usr/local/pkg/ruby/lib/ruby/1.9/webrick/server.rb:147 /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/proxy.rb:137:in `call' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/driver.rb:275:in `call' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/driver.rb:302:in `deposit' /usr/local/pkg/ruby/lib/ruby/1.9/soap/rpc/driver.rb:297:in `deposit' ./test/soap/header/test_authheader.rb:228:in `do_transaction_check' ./test/soap/header/test_authheader.rb:205:in `test_success_mu' 121 tests, 1172 assertions, 0 failures, 1 errors
こんなエラーは見たことがないな。 インタプリタ内で何か変なことが起きてそうな感じだ。 嫌すぎ。
(20:46)
誰の役に立つのかわからない Tru64UNIX ワンポイント
Tru64UNIX で、起動時に digital 21143 が half duplex になってしまうときは
# lan_config -i tu0 -a 1 -s 100 -x 1
とすると直るかもしれない。 tu0 はアタッチされているインターフェイス名とする。 インターフェイスの名前は ifconfig -a を見ればわかる。
(08:59)
[ruby-dev:25769] では解決したと書いたけど、 やっぱり解決してないようだ。 タイミングによってときどきプロセスが残ることがある。 もうちょっと何か考えよう。
(15:27)
Linux 本の練習問題に解答を書く。 と同時に、その解答に使うサンプルコードを書く。 ひたすら。
他のことも忘れてるわけじゃないのでもうちょっと待ってください……。
(15:29)
■
noritada [お、h1 がなくなってすっきり。と思いきや、
自分の環境 (Mac OS X の Firefox) だけかもしれませんが、
ページの下の方に h1 でどでかく「青木日記突込付」と (字が重なり合うようにして、というより重なり合って) 表示されちゃっていますです。
カレンダーの下です。
ご確認を (一応スクリーンショットも撮ってあるのでもしご希望ならどこかに置きます)。]
■ zunda [Linuxのfirefox-1.0-3mでも、行がおりかえされるとおりかさなる突込付。bodyからひきついでるline-heightが期待通りに動いてないみたいですねー。]
■
ょゎ [line-heightは % 指定だと、内側(?)での文字サイズ変更に追従してくれないらしいです。
150% でなく(単位無指定の)1.5 なら大丈夫かと。]
■
青木 [ううう、以前 BitChannel の CSS は直したのに
こっちは忘れてました……。]
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.
■ たむら [AMD64萌え〜だよね。JDSはなかなかカコイーし
思った以上にクライアントとして良く出来てると思う。
# ディレクトリ構造に慣れないといかんが]
■ 青木 [萌えですよねー AMD64 + Solaris。
一度は使ってみたい組み合わせです。]
■ なかだ [config.charsetを$(srcdir)に置いておくとiconv.rbというラッパーを作ります。
http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset
でもTru64UNIXだとCONFIG["target"]は何?]