From speakillof @ yahoo.co.jp Sat Jul 2 00:31:53 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Sat, 2 Jul 2005 00:31:53 +0900 (JST) Subject: [cgikit-dev 37] Re: Aspect Oriented Language: Logger and Profiler In-Reply-To: <3814665D-0066-4B8A-A1D9-BF2C8F286E43@spice-of-life.net> Message-ID: <20050701153153.21133.qmail@web2703.mail.mci.yahoo.co.jp> speakillofです。 aop.rb等をコミットしました。 aop.rbについては http://radio.s14.xrea.com/hiki/hiki.cgi?AOP をどうぞ。 > On 2005/06/27, at 19:00, speakillof wrote: > >> 私も他の使い道はわかりませんが、 > >> ログとプロファイルを取れるだけでも便利です。 > >> Aspectをコミットしていただければロギングを修正します。 > > じゃあ、テストを書いたらコミットしますね。 > > コミット先のディレクトリはどこにしますか? > > lib以下でも良いですが、lib/aopの方が適切かもしれません。 > > lib/aop/ でお願いします。 > AOPを使うCGIKit側のクラス (Loggingなど) は今ま > で通りlib/cgikit/ に置きます。 lib/aop/aop.rb lib/cgikit/logger_aspect.rb lib/cgikit/profiler_aspect.rb としてコミットしています。 使い方 require 'aop' require 'logger_aspect' require 'profiler_aspect' と ObjectSpace.each_object(Class) do |i| if CGIKit::Component > i or CGIKit::DynamicElement > i i.include_aspect Aspect::SimpleProfilerAspect, {:profile => /^append_to_/ } i.include_aspect Aspect::LoggerAspect, {:debug_context => /^invoke/} end end の二つをwebrickの実行スクリプトに挿入してやって CGIKit::Application#loggerを定義すれば、 それなりに動きます。 loggerとprofilerでは::Loggerオブジェクトの取得の仕方が違うので、 もし統一したい場合はおっしゃって下さい。 CGIKit-2.0.0-preview1のCKWikiのwebrick-app.rbで 標準エラーにログを出力した場合の実行例。 [2005-07-02 00:31:24] INFO WEBrick 1.3.1 [2005-07-02 00:31:24] INFO ruby 1.8.2 (2004-12-25) [i386-cygwin] [2005-07-02 00:31:24] INFO WEBrick::HTTPServer#start: pid=1304 port=8080 D, [2005-07-02T00:31:30.699256 #1304] DEBUG -- : CKWiki::MainPage#invoke_action: CGIKIt::Context: 0.0 D, [2005-07-02T00:31:30.708256 #1304] DEBUG -- : CKWiki::HeaderParts#invoke_action: CGIKIt::Context: 1.0 D, [2005-07-02T00:31:30.715256 #1304] DEBUG -- : CGIKit::GenericElement#invoke_action: CGIKIt::Context: 1.1 D, [2005-07-02T00:31:30.719256 #1304] DEBUG -- : CGIKit::GenericElement#invoke_action: CGIKIt::Context: 1.2 D, [2005-07-02T00:31:30.724256 #1304] DEBUG -- : CGIKit::String#invoke_action: CGIKIt::Context: 1.3 D, [2005-07-02T00:31:30.728256 #1304] DEBUG -- : CGIKit::String#invoke_action: CGIKIt::Context: 1.4 D, [2005-07-02T00:31:30.732256 #1304] DEBUG -- : CGIKit::Form#invoke_action: CGIKIt::Context: 1.5.0 D, [2005-07-02T00:31:30.736256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.1.0 D, [2005-07-02T00:31:30.750256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.2.0 D, [2005-07-02T00:31:30.758256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.3.0 D, [2005-07-02T00:31:30.763256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.4.0 D, [2005-07-02T00:31:30.767256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.5.0 D, [2005-07-02T00:31:30.773256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.6.0 D, [2005-07-02T00:31:30.778256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 1.5.7.0 D, [2005-07-02T00:31:30.782256 #1304] DEBUG -- : CGIKit::Conditional#invoke_action: CGIKIt::Context: 1.5.8.0 D, [2005-07-02T00:31:30.788256 #1304] DEBUG -- : CGIKit::TextField#invoke_action: CGIKIt::Context: 1.5.8.1 D, [2005-07-02T00:31:30.792256 #1304] DEBUG -- : CGIKit::Submit#invoke_action: CGIKIt::Context: 1.5.8.2 D, [2005-07-02T00:31:30.798256 #1304] DEBUG -- : CGIKit::Content#invoke_action: CGIKIt::Context: 1.6 D, [2005-07-02T00:31:30.803256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 0.2.0 D, [2005-07-02T00:31:30.807256 #1304] DEBUG -- : CGIKit::String#invoke_action: CGIKIt::Context: 0.3 D, [2005-07-02T00:31:30.813256 #1304] DEBUG -- : CGIKit::String#invoke_action: CGIKIt::Context: 0.4 D, [2005-07-02T00:31:30.818256 #1304] DEBUG -- : CGIKit::Repetition#invoke_action: CGIKIt::Context: 0.5.0 D, [2005-07-02T00:31:30.822256 #1304] DEBUG -- : CGIKit::Link#invoke_action: CGIKIt::Context: 0.5.1.0 D, [2005-07-02T00:31:30.844256 #1304] DEBUG -- : Sat Jul 02 00:31:30 GMT+9:00 2005 CGIKit::GenericElement#append_to_response: 0.00699996948242188 D, [2005-07-02T00:31:30.851256 #1304] DEBUG -- : Sat Jul 02 00:31:30 GMT+9:00 2005 CGIKit::GenericElement#append_to_response: 0.00199985504150391 ...... __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Sat Jul 2 21:08:55 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Sat, 2 Jul 2005 21:08:55 +0900 Subject: [cgikit-dev 38] Re: Aspect Oriented Language: Logger and Profiler In-Reply-To: <20050701153153.21133.qmail@web2703.mail.mci.yahoo.co.jp> References: <20050701153153.21133.qmail@web2703.mail.mci.yahoo.co.jp> Message-ID: <6C956990-E5BA-4C5B-A28F-C5BA75EA3EA8@spice-of-life.net> 鈴木です。 On 2005/07/02, at 0:31, speakillof wrote: > aop.rb等をコミットしました。 ありがとうございます。 ロギングを修正します。 > loggerとprofilerでは::Loggerオブジェクトの取得の仕 > 方が違うので、 > もし統一したい場合はおっしゃって下さい。 了解しました。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Wed Jul 13 07:50:13 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Wed, 13 Jul 2005 07:50:13 +0900 (JST) Subject: [cgikit-dev 39] package Message-ID: <20050712225013.7244.qmail@web3507.mail.bbt.yahoo.co.jp> speakillof です。 そろそろパーサー周りの修正をしようと思っているのですが、 package.rb が導入されて動かないところが出てきているので、 先にそちらに関して質問をさせて下さい。 1 パッケージについて 各プロジェクトには メインとなるパッケージと packages にインストールされるパッケージが存在して、 それぞれのパッケージは(デフォルト設定では)同一の ディレクトリ構造を持っていると考えて良いですか? (ディレクトリ構成はpackage.rbの先頭にある定数でおおよそ把握できる) また、必ず使用されるCGIKItパッケージはいずれ CVSにコミットされるんでしょうか? あと、メインパッケージの名前は実行パスに依存する気がしますけど、 それで良いですか? /usr/bin/hoge.rbがWEBrick用の実行スクリプトだとすると、 /usr/bin/hoge.rb cd /usr/bin; ./hoge.rb 上の二つではメインパッケージの名前が違いますよね。 2 package.rbのchdirは危険です。 CGIのように別プロセスとして実行される場合は良いですが、 WEBrick, mod_ruby の場合はプロセスで幾つかの CGIKit::Application のオブジェクトが走るので、require が変な動作を起こしそうです。 3 CGIKit::Application#required_packages でパッケージを追加することが可能ということでよいでしょうか? (packages ディレクトリにあるパッケージを 自動認識させても良いかもしれません) 4 path_for_component @component_path に絶対パスが入ると、 file_path, locale_path が変な値を返します。 CGIKit::Packageのインスタンス変数が相対パスだったり、 絶対パスだったりすることが原因です。 # どういう意図で実装しているのか # 私には分からないので修正できません。 @component_path に絶対パスが入る理由は resource.rb の 190行くらいのここです。 if @application.component_path then main.component_path = @application.component_path end 5 package_module unless Object.const_defined?(modname) then eval("module Object::#{modname};end") end の部分は unless Object.const_defined?(modname) then obj = Module.new Object.const_set(modname, obj) end でOKかと(試していませんが) # gettext がどう導入されるのか楽しみにしています。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Wed Jul 13 22:20:27 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Wed, 13 Jul 2005 22:20:27 +0900 Subject: [cgikit-dev 40] Re: package In-Reply-To: <20050712225013.7244.qmail@web3507.mail.bbt.yahoo.co.jp> References: <20050712225013.7244.qmail@web3507.mail.bbt.yahoo.co.jp> Message-ID: <3D46AB45-DD7A-41AE-93DF-96B46BCBAB75@spice-of-life.net> 鈴木です。 On 2005/07/13, at 7:50, speakillof wrote: > 1 パッケージについて > 各プロジェクトには メインとなるパッケージと > packages にインストールされるパッケージが存在して、 > それぞれのパッケージは(デフォルト設定では)同一の > ディレクトリ構造を持っていると考えて良いですか? > (ディレクトリ構成はpackage.rbの先頭にある定数でおおよそ > 把握できる) はい。メインパッケージ (アプリケーション) もパッケー ジのうちの1つです。 > また、必ず使用されるCGIKItパッケージはいずれ > CVSにコミットされるんでしょうか? data/cgikit/packages 以下に基本パッケージをコミットしてあります。 今のところ、エラーページコンポーネントとOutlineエレメント で使う 画像のみが入っています。 > あと、メインパッケージの名前は実行パスに依存する気がしますけど、 > それで良いですか? はい。 メインパッケージ名を指定する項目も後で追加します。 > 2 > package.rbのchdirは危険です。 > CGIのように別プロセスとして実行される場合は良いですが、 > WEBrick, mod_ruby の場合はプロセスで幾つかの CGIKit::Application > のオブジェクトが走るので、require が変な動作を起こしそう > です。 あ、気づきませんでした。 ディレクトリを降りてフックスクリプトを実行したかったのですが、 evalに修正しておきます。 > 3 > CGIKit::Application#required_packages > でパッケージを追加することが可能ということでよいでしょうか? > (packages ディレクトリにあるパッケージを > 自動認識させても良いかもしれません) はい。 ロードは自動認識のほうが楽ですね。 > 4 path_for_component > @component_path に絶対パスが入ると、 > file_path, locale_path が変な値を返します。 > CGIKit::Packageのインスタンス変数が相対パスだったり、 > 絶対パスだったりすることが原因です。 パッケージを導入したので、@component_pathは相対パスになり ます。 それまでは各ファイルのロードパスが曖昧だったので 絶対パスも想定していましたが、 1つのディレクトリ内にすべて収めるという方針になります。 > 5 package_module ... > unless Object.const_defined?(modname) then > obj = Module.new > Object.const_set(modname, obj) > end > > でOKかと(試していませんが) あ、そうですね。const_setに気づきませんでした。 修正します。 > # gettext がどう導入されるのか楽しみにしています。 以前のRubyスクリプトを利用したメッセージカテゴリをやめて、 試験的に実装してあります。 gettextを導入すると別途gettextのインストールが必要になるので 躊躇していたのですが、よくよく調べてみると mo フォーマットのファイルさえ使えればいいことがわかりました。 幸いgettextでは mo.rb として独立しており、これを同梱 することで CGIKit単体でgettext形式のファイルを扱えるようになります。 (mo.rb は lib/cgikit/lang/mo.rb にコミット済みです) 使い方は、パッケージの locale/各言語/messages ディレ クトリに *.mo ファイルを配置します。 HelloWorld/ locale/ ja/ messages/ default.mo あとは Component#message でキーを指定すれば、 各言語のパッケージからメッセージカテゴリを引っ張ってきます。 ファイルを省略すると default.mo が使われ、 gettextのような _('%d files are removed.') というコードで メッセージを取得することができます。 # のちのちメッセージカテゴリも含めた # パッケージ作成のサンプルを追加する予定です。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Thu Jul 14 02:00:06 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Thu, 14 Jul 2005 02:00:06 +0900 (JST) Subject: [cgikit-dev 41] Re: package In-Reply-To: <3D46AB45-DD7A-41AE-93DF-96B46BCBAB75@spice-of-life.net> Message-ID: <20050713170006.6746.qmail@web3507.mail.bbt.yahoo.co.jp> speakillofです。 お返事ありがとうございました。 なんとなくですが、イメージをつかむことが出来ました。 必要なところだけ補足をお願いしたいのですが。 > 鈴木です。 > > > また、必ず使用されるCGIKItパッケージはいずれ > > CVSにコミットされるんでしょうか? > > data/cgikit/packages 以下に基本パッケージをコミットしてあります。 > 今のところ、エラーページコンポーネントとOutlineエレメント > で使う画像のみが入っています。 かならず必要となるということは 今後は data/cgikit/packages 以下の内容が ckprojectで配置されることになるんでしょうか? > > 2 > > package.rbのchdirは危険です。 > > CGIのように別プロセスとして実行される場合は良いですが、 > > WEBrick, mod_ruby の場合はプロセスで幾つかの CGIKit::Application > > のオブジェクトが走るので、require が変な動作を起こしそう > > です。 > > あ、気づきませんでした。 > ディレクトリを降りてフックスクリプトを実行したかったのですが、 > evalに修正しておきます。 たぶん、開発者にはそちらのほうが優しいと思うのですが、 複数Threadで動くことを考えると厳しいですね。 > > # gettext がどう導入されるのか楽しみにしています。 > > 以前のRubyスクリプトを利用したメッセージカテゴリをやめて、 > 試験的に実装してあります。 > > gettextを導入すると別途gettextのインストールが必要になるので > 躊躇していたのですが、よくよく調べてみると > mo フォーマットのファイルさえ使えればいいことがわかりました。 > 幸いgettextでは mo.rb として独立しており、これを同梱 > することで > CGIKit単体でgettext形式のファイルを扱えるようになります。 > (mo.rb は lib/cgikit/lang/mo.rb にコミット済みです) > > 使い方は、パッケージの locale/各言語/messages ディレ > クトリに > *.mo ファイルを配置します。 > > HelloWorld/ > locale/ > ja/ > messages/ > default.mo > > あとは Component#message でキーを指定すれば、 > 各言語のパッケージからメッセージカテゴリを引っ張ってきます。 > ファイルを省略すると default.mo が使われ、 > gettextのような _('%d files are removed.') というコードで > メッセージを取得することができます。 ckdファイルで { :hoge => { :element => String, :value => _("hogehoge") } } としたいんですが、無理ですね・・・。 ckdファイル内は実行コンテキストが CGIKit::ComponentやCGIKit::DirectAction ではないですから。 # それと、今のCGIKitはckdファイルのevalの結果が # 必ず同じ値を返すことを期待していますが、 # _() を使うと言語ごとに違う値になってしまいます。 そのため Hoge.ckd { :hoge => { :element => String, :value => :msg } } Hoge.rb class Hoge < CGIKit::Component def msg _("hogehoge") end end と分離しないと駄目でしょうね。 ちょっと悩ましいかもしれません。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Thu Jul 14 17:40:39 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Thu, 14 Jul 2005 17:40:39 +0900 Subject: [cgikit-dev 42] Re: package In-Reply-To: <20050713170006.6746.qmail@web3507.mail.bbt.yahoo.co.jp> References: <20050713170006.6746.qmail@web3507.mail.bbt.yahoo.co.jp> Message-ID: <66327600-1307-457E-BB3F-207984C4DE41@spice-of-life.net> 鈴木です。 On 2005/07/14, at 2:00, speakillof wrote: >> data/cgikit/packages 以下に基本パッケージをコミットしてありま >> す。 >> 今のところ、エラーページコンポーネントとOutlineエレメント >> で使う画像のみが入っています。 > かならず必要となるということは > 今後は data/cgikit/packages 以下の内容が > ckprojectで配置されることになるんでしょうか? いえ、パッケージは複数のパスから探すようになっていまして、 ckprojectでコピーすることはありません。 アプリケーションディレクトリの packages/ の他に /usr/share/data/cgikit/packages, ./data/cgikit/packages が検索対象となります。 そのため、手動でのCGIKitのインストールは lib 以下と data 以下をコピーすることになります。 >>> # gettext がどう導入されるのか楽しみにしています。 >> 以前のRubyスクリプトを利用したメッセージカテゴリをやめ >> て、 >> 試験的に実装してあります。 ... > そのため > > Hoge.ckd > { > :hoge => { > :element => String, > :value => :msg > } > } > > Hoge.rb > > class Hoge < CGIKit::Component > > def msg > _("hogehoge") > end > > end > > と分離しないと駄目でしょうね。 > ちょっと悩ましいかもしれません。 そうですね、そこだけ少し面倒かもしれません。 一応シンボルで式自体を書いてしまえばできることはできますが。 { :hoge => { :element => String, :value => :"_('...')" } } ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Sun Jul 17 01:16:59 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Sun, 17 Jul 2005 01:16:59 +0900 (JST) Subject: [cgikit-dev 43] Re: package In-Reply-To: <66327600-1307-457E-BB3F-207984C4DE41@spice-of-life.net> Message-ID: <20050716161659.84766.qmail@web3503.mail.bbt.yahoo.co.jp> --- SUZUKI Tetsuya からのメッセージ: > 鈴木です。 > > On 2005/07/14, at 2:00, speakillof wrote: > >> data/cgikit/packages 以下に基本パッケージをコミットしてありま > >> す。 > >> 今のところ、エラーページコンポーネントとOutlineエレメント > >> で使う画像のみが入っています。 > > かならず必要となるということは > > 今後は data/cgikit/packages 以下の内容が > > ckprojectで配置されることになるんでしょうか? > > いえ、パッケージは複数のパスから探すようになっていまして、 > ckprojectでコピーすることはありません。 > アプリケーションディレクトリの packages/ の他に > /usr/share/data/cgikit/packages, ./data/cgikit/packages > が検索対象となります。 > > そのため、手動でのCGIKitのインストールは > lib 以下と data 以下をコピーすることになります。 インストールしないで使う人にとっては 一手間増えますね。 シンボリックリンクを増やすか、 CGIKit::Application#package_paths を設定するかすれば 良いだけなので、どうって事は無いんですが…。 仕方ないかな。 ちなみに 7/16 の cgikit/application.rb の 396行目 のawake_from_restorationの引数が間違っているみたいです。 if session then context.session = session context.session.awake_from_restoration(self, context.request) context.session.validate end 手元ではこれで動きますけど、御検証ください。 # 例によって一行パッチなので、 # diff は無しです。 > > > > Hoge.ckd > > { > > :hoge => { > > :element => String, > > :value => :msg > > } > > } > > > > Hoge.rb > > > > class Hoge < CGIKit::Component > > > > def msg > > _("hogehoge") > > end > > > > end > > > > と分離しないと駄目でしょうね。 > > ちょっと悩ましいかもしれません。 > > そうですね、そこだけ少し面倒かもしれません。 > 一応シンボルで式自体を書いてしまえばできることはできますが。 > > { > :hoge => { > :element => String, > :value => :"_('...')" > } > } あ、なるほど。 でも、これは少し困るかな・・・かな。 これから KeyValueCoding をいじって hoge.foo.bar のような単純なメソッドチェーン(OGNLの簡易なもの)に 限って Object#__send__ で実装しなおそうと思っています。 最終的には eval系 を使わざるを得ないのですが、 上の式( _("") )は __send__ での実装は面倒かもしれません。 ま、後でやってみます。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Sun Jul 17 21:49:55 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Sun, 17 Jul 2005 21:49:55 +0900 Subject: [cgikit-dev 44] Re: package In-Reply-To: <20050716161659.84766.qmail@web3503.mail.bbt.yahoo.co.jp> References: <20050716161659.84766.qmail@web3503.mail.bbt.yahoo.co.jp> Message-ID: <4BB2ABA1-319B-4D42-859C-B6F354802AD1@spice-of-life.net> 鈴木です。 On 2005/07/17, at 1:16, speakillof wrote: > ちなみに 7/16 の cgikit/application.rb の > 396行目 > のawake_from_restorationの引数が間違っているみたいです。 ... > 手元ではこれで動きますけど、御検証ください。 あ、忘れていました。ありがとうございます。 修正しておきました。 > これから KeyValueCoding をいじって > > hoge.foo.bar > > のような単純なメソッドチェーン(OGNLの簡易なもの)に > 限って Object#__send__ で実装しなおそうと思っています。 > 最終的には eval系 を使わざるを得ないのですが、 > 上の式( _("") )は __send__ での実装は面倒かもしれ > ません。 以前Object#__send__を使ってパフォーマンスを調べたことがあ りますが、 instance_evalのほうが高速でした。 次が実装してみたコードです。 def value_for_keypath( keypath ) obj = self keypath.split('.').each do |key| obj = obj.__send__(key) end obj end ところで、今試しにテンプレート用の仮想マシンを作っています。 現在の実装でベンチマークをとってみると ノードをたどるArray#eachの負荷が大きいので、 それをなくすことができれば速くなるかもしれません、 うまくいきそうであれば、KeyValueCodingも含め 一部の拡張ライブラリバージョンを用意してみようかと思います。 # メンテナンスは難しくなりますが。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Mon Jul 18 02:52:17 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Mon, 18 Jul 2005 02:52:17 +0900 (JST) Subject: [cgikit-dev 45] Re: package In-Reply-To: <4BB2ABA1-319B-4D42-859C-B6F354802AD1@spice-of-life.net> Message-ID: <20050717175217.84970.qmail@web3508.mail.bbt.yahoo.co.jp> speakillof です。 > 鈴木です。 > > > これから KeyValueCoding をいじって > > > > hoge.foo.bar > > > > のような単純なメソッドチェーン(OGNLの簡易なもの)に > > 限って Object#__send__ で実装しなおそうと思っています。 > > 最終的には eval系 を使わざるを得ないのですが、 > > 上の式( _("") )は __send__ での実装は面倒かもしれ > > ません。 > > 以前Object#__send__を使ってパフォーマンスを調べたことがあ > りますが、 > instance_evalのほうが高速でした。 > 次が実装してみたコードです。 > > def value_for_keypath( keypath ) > obj = self > keypath.split('.').each do |key| > obj = obj.__send__(key) > end > obj > end 似たようなコードを書いた後でした(苦笑) instance_eval ということで、GCが遅くなるような条件を 整えてやれば逆転しますが、あくまでベンチマーク上の話です。 他にこの部分で最適化できるとすれば、value_for_keypath の 呼出をまとめて一括して instance_eval を 行う事でしょうか。GC の回数が減って早くなるはずです。 > ところで、今試しにテンプレート用の仮想マシンを作っています。 > 現在の実装でベンチマークをとってみると > ノードをたどるArray#eachの負荷が大きいので、 > それをなくすことができれば速くなるかもしれません、 > > うまくいきそうであれば、KeyValueCodingも含め > 一部の拡張ライブラリバージョンを用意してみようかと思います。 ノードをたどらないようにするために take_values, invoke に必要なノードだけを 構文木の最上位のノードに持たせる事はできると思います。 append は仮想マシンかコンパイラが必要になりますね。 うーん。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Tue Jul 19 04:05:33 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Tue, 19 Jul 2005 04:05:33 +0900 Subject: [cgikit-dev 46] Re: package In-Reply-To: <20050717175217.84970.qmail@web3508.mail.bbt.yahoo.co.jp> References: <20050717175217.84970.qmail@web3508.mail.bbt.yahoo.co.jp> Message-ID: <414A098F-C950-4ACD-99E4-FDAA9CB1777F@spice-of-life.net> 鈴木です。 On 2005/07/18, at 2:52, speakillof wrote: > 他にこの部分で最適化できるとすれば、value_for_keypath の > 呼出をまとめて一括して instance_eval を > 行う事でしょうか。GC の回数が減って早くなるはずです。 value_for_keypathはvalue_for_keyのエイリアスなので、 一括してinstance_evalしています。 sendもevalも使わない方法として、 ckdの属性値をメソッドにしたらどうでしょう。 :my_name => { :element => String, :value => :'hoge.foo.bar' } なら class MainPage < Component def hoge_foo_bar hoge.foo.bar end end とメソッドを定義して使い回します。 単純なメソッドチェーン以外の式もメソッドにしてしまえばいいかもし れません。 >> ところで、今試しにテンプレート用の仮想マシンを作っています。 >> 現在の実装でベンチマークをとってみると >> ノードをたどるArray#eachの負荷が大きいので、 >> それをなくすことができれば速くなるかもしれません、 > ノードをたどらないようにするために > take_values, invoke に必要なノードだけを > 構文木の最上位のノードに持たせる事はできると思います。 > > append は仮想マシンかコンパイラが必要になりますね。 > うーん。 CGIKitNodeを生成して互換性をとろうとしてみましたが、難しいですね。 VM側で完全にCGIKitNodeを置き換えるしかなさそうです。 # VM自体は思ったより単純にできそうです。 # 処理がテキストを表示するかエレメントを生成するかのどちらかです から。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From suzuki @ spice-of-life.net Wed Jul 20 00:52:06 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Wed, 20 Jul 2005 00:52:06 +0900 Subject: [cgikit-dev 47] Re: package In-Reply-To: <414A098F-C950-4ACD-99E4-FDAA9CB1777F@spice-of-life.net> References: <20050717175217.84970.qmail@web3508.mail.bbt.yahoo.co.jp> <414A098F-C950-4ACD-99E4-FDAA9CB1777F@spice-of-life.net> Message-ID: <041CE608-3A04-4DDF-9C9B-92F3FB034F9A@spice-of-life.net> On 2005/07/19, at 4:05, SUZUKI Tetsuya wrote: > CGIKitNodeを生成して互換性をとろうとしてみましたが、難しいです > ね。 > VM側で完全にCGIKitNodeを置き換えるしかなさそうです。 > > # VM自体は思ったより単純にできそうです。 > # 処理がテキストを表示するかエレメントを生成するかのどちらかで > すから。 HelloWorldくらいの簡単なテンプレートくらいなら 表示できるようになりましたが、あまり効果がないようです。 1.0 - 1.1 倍くらいの速度しか出ません。 エレメントの数が増えるとかえって遅くなることさえあります。 現状のノードのまま高速化を考えるほうがいいですね、これじゃ。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From suzuki @ spice-of-life.net Wed Jul 20 14:52:20 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Wed, 20 Jul 2005 14:52:20 +0900 Subject: [cgikit-dev 48] Re: package In-Reply-To: <414A098F-C950-4ACD-99E4-FDAA9CB1777F@spice-of-life.net> References: <20050717175217.84970.qmail@web3508.mail.bbt.yahoo.co.jp> <414A098F-C950-4ACD-99E4-FDAA9CB1777F@spice-of-life.net> Message-ID: <2062E272-9EB4-472D-A8E2-F6E98C37F390@spice-of-life.net> 鈴木です。 On 2005/07/19, at 4:05, SUZUKI Tetsuya wrote: > sendもevalも使わない方法として、 > ckdの属性値をメソッドにしたらどうでしょう。 ... > とメソッドを定義して使い回します。 > 単純なメソッドチェーン以外の式もメソッドにしてしまえばいいかも > しれません。 Methodオブジェクトを使ってvalue_for_keyを書き直してみまし たが、 これもたいして効果がないようです。 ほぼinstance_evalと同程度か、若干遅くなります。 module KeyValueCoding def _getter_method( key ) @_getter_methods ||= {} unless id = @_getter_methods[key] then id = @_getter_methods.size + 1 @_getter_methods[key] = id instance_eval("def __value_for_#{id};#{key};end") end method("__value_for_#{id}") end # Retrieves value for the key. def value_for_key( __key ) method = _getter_method(__key) method.call end end ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Thu Jul 21 22:05:04 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Thu, 21 Jul 2005 22:05:04 +0900 (JST) Subject: [cgikit-dev 49] Re: package In-Reply-To: <041CE608-3A04-4DDF-9C9B-92F3FB034F9A@spice-of-life.net> Message-ID: <20050721130504.41893.qmail@web3503.mail.bbt.yahoo.co.jp> speakillofです。 > > CGIKitNodeを生成して互換性をとろうとしてみましたが、難しいです > > ね。 > > VM側で完全にCGIKitNodeを置き換えるしかなさそうです。 > > > > # VM自体は思ったより単純にできそうです。 > > # 処理がテキストを表示するかエレメントを生成するかのどちらかで > > すから。 > > HelloWorldくらいの簡単なテンプレートくらいなら > 表示できるようになりましたが、あまり効果がないようです。 > 1.0 - 1.1 倍くらいの速度しか出ません。 > エレメントの数が増えるとかえって遅くなることさえあります。 > 現状のノードのまま高速化を考えるほうがいいですね、これじゃ。 うーん、そうですか。 最適化を考える前にどこがボトルネックなのか 導入した profiler_aspect.rb で調べてみました。 examples/Calc/webrick-app.rb の require が並んだ所に Aspect::SimpleProfilerAspect.init_profiler("hogehoge") class MainPage < CGIKit::Component include_aspect Aspect::SimpleProfilerAspect, { :profile => /append_to|take_values_from_re|invoke_/ } end こんな感じの行を加えて、webrick-app.rbを起動します。 ブラウザでアクセスすると、 実行時のディレクトリにプロファイリング(というかベンチマーク?)の 結果が出力されます。 # Logfile created on Thu Jul 21 21:44:21 GMT+9:00 2005 by logger.rb/1.5.2.4 D, [2005-07-21T21:44:31.325003 #552] DEBUG -- : Thu Jul 21 21:44:31 GMT+9:00 2005 MainPage#take_values_from_request: 0.00499987602233887 D, [2005-07-21T21:44:31.333003 #552] DEBUG -- : Thu Jul 21 21:44:31 GMT+9:00 2005 MainPage#invoke_action: 0.00600004196166992 D, [2005-07-21T21:44:31.341003 #552] DEBUG -- : Thu Jul 21 21:44:31 GMT+9:00 2005 MainPage#append_to_response: 0.00799989700317383 D, [2005-07-21T21:44:34.132003 #552] DEBUG -- : Thu Jul 21 21:44:34 GMT+9:00 2005 MainPage#take_values_from_request: 0.00500011444091797 D, [2005-07-21T21:44:34.137003 #552] DEBUG -- : Thu Jul 21 21:44:34 GMT+9:00 2005 MainPage#invoke_action: 0.00399994850158691 D, [2005-07-21T21:44:34.144003 #552] DEBUG -- : Thu Jul 21 21:44:34 GMT+9:00 2005 MainPage#append_to_response: 0.00599980354309082 (自分でいうのもなんですが、Ruby 標準の profiler と違って 対象とするメソッドだけをプロファイルしたいときには profiler_aspect.rbは便利です。) 見たらわかるように take_values, invoke, append の三者については ほとんど同じ時間かかっています。 今回は append については考えないで、 take_values, invoke の最適化についてやってみます。 (DirectActionへの恩恵はないですが...) 私が考えている方法としては 1 ノードの生成時に CGIKitNode だけを抽出しておいて、 エレメントIDをキーとするHashとして最上位ノードに持たせる。 2 take_values, invoke ではエレメントID -> CGIKitNode なHash をつかって必要なノードだけをたどる です。上手くいくかどうかは元の take_values, invoke の実装次第ですね。 こったことをしていると、上の方法では破綻しそうです。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From speakillof @ yahoo.co.jp Sat Jul 23 09:07:38 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Sat, 23 Jul 2005 09:07:38 +0900 (JST) Subject: [cgikit-dev 50] CGIKit::Context Message-ID: <20050723000738.42048.qmail@web3509.mail.bbt.yahoo.co.jp> speakillof です。 3点質問があります。 1 take, invoke, append の実行時に CGIKit::Context を介して Context ID, component ID, element ID を設定する理由は何でしょうか? ComponentRequestHandler ではそれぞれのフェーズでIDを振りなおすので、 遅くなります(どの程度遅くなっているのか見積もれないのですが...)。 IDをふるだけならテンプレートの解析時にも可能ですが、 わざわざ遅延させている理由は CGIKit::Context を 差し替え可能にするためですか? それとも、take, invoke, append の実行時に 木構造をいじるための余地を残すためですか? # 前者の理由であれば、テンプレート解析時に Context オブジェクトに # ノードをたどらせて ID を振ってもらうことができます。 # 後者であれば、テンプレート解析時に ID を振って高速化するのは無理です ね。 2 CGIKit::Component#begin_context の実行中の CGIKit::Context#init_component_id_with_session の unless component_id = session.component_id(component) then # register current component with ID for creating new session component_id = component_id() || @session.next_component_id @session.add_component_for_ids(component, component_id, context_id()) @session.save_page(component) component_id = session.component_id(component) end この部分の @session.save_page が理解できません(情けない...)。 以前から気になっていたのですが、 CGIKit::Sessionの @caches, @permanent_caches でキャッシュされた値はどこで使われているのでしょう? # grep をかけても該当する場所が見つけられませんでした。 3 トップコンポーネント の CGIKit::Component#begin_context ですでに (rdb:2) p @contexts [0] (rdb:2) p @counts [] となるのですが、initialize の後、begin_context の前で @contexts の値が設定されてるのはどこでしょうか? __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Sat Jul 23 21:15:16 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Sat, 23 Jul 2005 21:15:16 +0900 Subject: [cgikit-dev 51] Re: CGIKit::Context In-Reply-To: <20050723000738.42048.qmail@web3509.mail.bbt.yahoo.co.jp> References: <20050723000738.42048.qmail@web3509.mail.bbt.yahoo.co.jp> Message-ID: <779E5BB6-C3BF-43AF-812C-87884410AC70@spice-of-life.net> 鈴木です。 On 2005/07/23, at 9:07, speakillof wrote: > 1 > take, invoke, append の実行時に CGIKit::Context を介して > Context ID, component ID, element ID を設定する理由は何でしょ > うか? > ComponentRequestHandler ではそれぞれのフェーズでIDを振り > なおすので、 > 遅くなります(どの程度遅くなっているのか見積もれないので > すが...)。 IDを振るためです。各フェーズで振り直すのは、 RepetitionによってIDが増減するためです。 あ、でもRepetition内ではIDが一桁増えるので、 テンプレート解析時に振っておくことはできますね。 > 2 > CGIKit::Component#begin_context の実行中の > CGIKit::Context#init_component_id_with_session の ... > この部分の @session.save_page が理解できません(情 > けない...)。 Session#save_pageでは、コンポーネントを保存すると同時に コンポーネントIDが発行されます。 それをコンポーネントにセットしています。 Session#save_pageは他の箇所でも何度か出てきますが、 コンポーネントIDを発行するたびにすべてコンポーネントを 保存するのは無駄があるかもしれません。 (特にFileSessionStoreの場合) > 以前から気になっていたのですが、 CGIKit::Sessionの > @caches, > @permanent_caches でキャッシュされた値はどこで使われているので > しょう? * Session#component_id * Session#component_for_component_id * Session#component_for_context_id, _component で使っています。 > トップコンポーネント の > CGIKit::Component#begin_context ですでに > > (rdb:2) p @contexts > [0] > (rdb:2) p @counts > [] > > となるのですが、initialize の後、begin_context の > 前で > @contexts の値が設定されてるのはどこでしょうか? Context#context_id= です。 ここで設定した値が解析され、@contextsになります。 begin_contextの前でこれが呼ばれている箇所はありません。 Component#begin_contextでコンポーネントIDが発行され、 そのIDが context にセットされます。 @contexts の内容は [コンポーネントID] になります。 [0]や[1]など。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Sun Jul 24 01:19:24 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Sun, 24 Jul 2005 01:19:24 +0900 (JST) Subject: [cgikit-dev 52] =?iso-2022-jp?b?YmFzaWMgGyRCRyc+WhsoQg==?= Message-ID: <20050723161924.31801.qmail@web3510.mail.bbt.yahoo.co.jp> speakillof です。 # CGIKit::Contextが結構いろいろやっているので、 # 挫折気味です。 現実逃避して CGIKitで Basic 認証を使えるかどうか 試してみました。 元ネタはこちらです。 http://d.hatena.ne.jp/secondlife/20050629 basic.rb がbasic 認証のためのライブラリ。 (というか webrick/httpauth/basicauth.rb のラッパー) hoge.rbが WEBrick 用スクリプトです。 両者を examples/Calc に置いて ruby hoge.rb で実行して、 http://localhost:8080/d/Hoge にアクセスしてください。 ユーザー名とパスワードを聞かれたら、 username supersecretpass を入力してください。 上手くいけば電卓の画面が表示されます。 元ネタは AOP を使っていますが、私は AOP を使うことには 否定的なんですよね...。 # ところで、basic認証の ID・passwordって HTTP_AUTHORIZATION # フィールドに入るということで良いのでしょうか?分からない...。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ -------------- next part -------------- テキスト形式以外の添付ファイルを保管しました... ファイル名: basic.rb 型: application/octet-stream サイズ: 938 バイト 説明: basic.rb URL: http://lists.sourceforge.jp/mailman/archives/cgikit-dev/attachments/20050724/db639488/attachment.obj -------------- next part -------------- テキスト形式以外の添付ファイルを保管しました... ファイル名: hoge.rb 型: application/octet-stream サイズ: 918 バイト 説明: hoge.rb URL: http://lists.sourceforge.jp/mailman/archives/cgikit-dev/attachments/20050724/db639488/attachment-0001.obj From suzuki @ spice-of-life.net Sun Jul 24 14:32:46 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Sun, 24 Jul 2005 14:32:46 +0900 Subject: [cgikit-dev 53] =?iso-2022-jp?b?UmU6IGJhc2ljIBskQkcnPlobKEI=?= In-Reply-To: <20050723161924.31801.qmail@web3510.mail.bbt.yahoo.co.jp> References: <20050723161924.31801.qmail@web3510.mail.bbt.yahoo.co.jp> Message-ID: 鈴木です。 On 2005/07/24, at 1:19, speakillof wrote: > # CGIKit::Contextが結構いろいろやっているので、 > # 挫折気味です。 私も実装に自信がないです。なんとか動かしている程度です。 > 現実逃避して CGIKitで Basic 認証を使えるかどうか > 試してみました。 結構簡単にできるもんなんですね。 元ネタのFilterとまでいかなくても、このくらいの抽象化のほうが 使いやすいと思います。 > 元ネタは AOP を使っていますが、私は AOP を使うこと > には > 否定的なんですよね...。 RailsのFilterがAOPと言うほどAOPとは思えませ ん。:-P まあAOPうんぬんは別として、Basic認証の場合 (と CGIKitの場合) は Filterほど自動化してしまうとかえって使いづらいと思います。 > # ところで、basic認証の ID・passwordって > HTTP_AUTHORIZATION > # フィールドに入るということで良いのでしょうか?分からな > い...。 CGIの標準でもないようですし、たまたま各サーバが HTTP_AUTHORIZATION に対応しているだけではないでしょうか。 ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/ From speakillof @ yahoo.co.jp Mon Jul 25 03:29:51 2005 From: speakillof @ yahoo.co.jp (speakillof) Date: Mon, 25 Jul 2005 03:29:51 +0900 (JST) Subject: [cgikit-dev 54] =?iso-2022-jp?b?UmU6IGJhc2ljIBskQkcnPlobKEI=?= In-Reply-To: Message-ID: <20050724182951.60735.qmail@web3501.mail.bbt.yahoo.co.jp> speakillofです。 > 鈴木です。 > > On 2005/07/24, at 1:19, speakillof wrote: > > # CGIKit::Contextが結構いろいろやっているので、 > > # 挫折気味です。 > > 私も実装に自信がないです。なんとか動かしている程度です。 時間のあるときに試してみます。 気長にやるつもりです。 > > 現実逃避して CGIKitで Basic 認証を使えるかどうか > > 試してみました。 > > 結構簡単にできるもんなんですね。 そのうち Digest認証 についてもやりたいですね。 # 私が作る最初のパッケージは認証用パッケージが良いかな。 > 元ネタのFilterとまでいかなくても、このくらいの抽象化のほうが > 使いやすいと思います。 うーん。個人的には * authenticate の返り値とエラー送出の是非 * response オブジェクトの設定 で悩んでいます。もともとのWEBrick の Basic 認証用 ライブラリでは authenticate で認証に失敗すると、 falseを返さずエラーを出すようになっています。 この時 response オブジェクト(もちろんWEBrick用)に 自動的に認証失敗の情報が設定されます。 (401 Authorization Required) CGIKit::BasicAuth#authenticate ではエラーの代わりに false を返すようにしていますが、 CGIKit::Response に認証失敗の設定は行います。 このあたりはライブラリの挙動として どっちが良いのか悩んでます。 > > 元ネタは AOP を使っていますが、私は AOP を使うこと > > には否定的なんですよね...。 > > RailsのFilterがAOPと言うほどAOPとは思えませ > ん。:-P うーん、私は AOP かなって思いますが・・・。 確かにAspectRほどではないでしょうけど、 一応 before, after でメソッドの折込が出来ますし・・・。 # aop/aop.rb の方が汎用的に作ってあるつもりですけど。 > まあAOPうんぬんは別として、Basic認証の場合 (と > CGIKitの場合) は > Filterほど自動化してしまうとかえって使いづらいと思います。 たとえば、 class FooAction < CGIKit::DirectAction def foo1_action ... end def foo2_action ... end ... end となっていて、全ての *_action なメソッドで認証が必要な場合は AOP を使ったほうが楽は楽です。(諸刃の刃ですけど) hoge.rb では認証が必要なページがひとつですから、 べたに書いていますが、認証の必要なページが増えると 認証の部分で同じコードがいっぱい出現することになります。 __________________________________ Save the earth http://pr.mail.yahoo.co.jp/ondanka/ From suzuki @ spice-of-life.net Mon Jul 25 21:58:04 2005 From: suzuki @ spice-of-life.net (SUZUKI Tetsuya) Date: Mon, 25 Jul 2005 21:58:04 +0900 Subject: [cgikit-dev 55] =?iso-2022-jp?b?UmU6IGJhc2ljIBskQkcnPlobKEI=?= In-Reply-To: <20050724182951.60735.qmail@web3501.mail.bbt.yahoo.co.jp> References: <20050724182951.60735.qmail@web3501.mail.bbt.yahoo.co.jp> Message-ID: <8E6F61BE-3549-4A7A-A0F0-AD91F71282AB@spice-of-life.net> 鈴木です。 On 2005/07/25, at 3:29, speakillof wrote: >> 元ネタのFilterとまでいかなくても、このくらいの抽象化の >> ほうが >> 使いやすいと思います。 ... > CGIKit::BasicAuth#authenticate ではエラーの代わりに > false を返すようにしていますが、 > CGIKit::Response に認証失敗の設定は行います。 > このあたりはライブラリの挙動として > どっちが良いのか悩んでます。 今のままでもいいと思いますが、 CGIKit::BasicAuth#authenticateで例外を発生させて Applicationで捕捉するのもいいかもしれません。 # Applicationに任意の例外と捕捉するメソッドを登録できるといいか も。 >> RailsのFilterがAOPと言うほどAOPとは思えませ >> ん。:-P > うーん、私は AOP かなって思いますが・・・。 > 確かにAspectRほどではないでしょうけど、 > 一応 before, after でメソッドの折込が出来ますし・・・。 よく見る方法ですから、そんなにAOPと言うほどなのかな…と思 いましたが、 あ、メソッド単位でbefore, afterが設定できるということです か。 ああ、それは便利ですね (笑) >> まあAOPうんぬんは別として、Basic認証の場合 >> (と >> CGIKitの場合) は >> Filterほど自動化してしまうとかえって使いづらいと思います。 > たとえば、 ... > となっていて、全ての *_action なメソッドで認証が必要な場 > 合は > AOP を使ったほうが楽は楽です。(諸刃の刃ですけど) うーん、便利とは思いますが、AOPを使うほど必要かどうかわか りません。 簡単な処理なら1つで済ませられるメソッドを用意するだけでも 十分かなと思います。 (hoge.rbのdefault_actionがメソッド1つで処理できる、 など) ----------------------------------- 鈴木鉄也 (SUZUKI Tetsuya) suzuki @ spice-of-life.net http://www.spice-of-life.net/