/ 最近 .rdf 追記 設定 本棚

log[Ruby: 2008-04-17]



20080417() JavaScriptHTMLを初めてさわったのは Win98「フォルダのカスタマイズWMPを埋め込んで試聴できるようにしたり

[tDiary][Ruby] CGI.escapeERB::Util.u の違い

http://tdiary.cvs.sourceforge.net/tdiary/plugin/category.rb?revision=1.45.2.1&view=markup&sortby=date&pathrev=Stable-2_2

  • 」が%20になる(ERB::Util.u)
  • 」が+になる(CGI.escape)

気付いたのは日記を書くときにカテゴリ名入力支援機能(クリックすると本文にカテゴリが挿入される*)のカテゴリリトに目当てのカテゴリがなかったから

脱線何かのソースを見たときに思ったのだけど ERB::Util.uCGI.escape もエンコドしすぎだと感じてる人がいるみたい(一部の記号をわざわざ復号していたたしかに %XXURLに現れるのは美しくない)

閑休存在するはずのカテゴリファイルがなくてエラーを出していたのはここ(20071208p01)で自分が書いた tdiary/categorizedio.rbったので誰にでも起こる不具合なのか確証がなかったり

http://tdiary-users.sourceforge.jp/cgi-bin/wforum/wforum.cgi?mode=allread&no=5718&page=0

tDiary標準のカテゴリモドがどのようになるのかは未確認だったり

複数のポトを日付で括ってしまう tDiary(<日記だから)はどうしても <title>タグの中身が味気なくなってしまってトにも人間にもアピールが弱いなとか全然関係ないけどいま思った(BlogKitでは解決してそ)

ぼそり(category.rb@conf.data_path'category'を連結するときにパスセパレータを二重化してる問題はレンタルサーバ(FreeBSD)でもローカル(Windows)でも起きていないがそういうのが気持ちわるい&気にしたくないので自分は File.joinScripting.FileSystemObject.BuildPathを必ず使)

* 本文の末尾でなくカーソル位置にカテゴリを挿入するための変更はこちら > http://www.kde.ics.tut.ac.jp/%7Efrsh/tdiary/?date=20071220#p01

 Firefox3はデコドした URLをロケーションバーに表示してクリップボドにはエンコドした URLをコピーするので二重にエンコドされた部分が含まれるAmazonやブックマークサービスの URLでしか %XX を見ることはなくなりそう


20080404() *ss[]sizeof の結果も違っていたはず。仮引数に s[]とも書けるのはデメリトでしかない実際はポインタなのだから

最終更: 2012-01-26T13:29+0900

[Ruby] 最近は Cのポインタが流行りらしい

Rubyに来たときは意識しなかったが最近 Ruby側から C++を眺めたときにあまりの違いに恐れおののいたこと(限りあるスタックの使いすぎに注意しようね)

 C++の変数はごついあるは近い (蛇足もちろん全てがそうとは言わな)

# Ruby
myobject = MyClass.new();
// C++
MyClass myobject;
MyClass *pmyobject = &myobject;

Rubyでは MyClass.new()MyClassのイスタスを作りそれを後から参照するために myobjectという名札を貼り付けているC++では MyClass myobject; だけで既にイスタスが存在していて名札を貼り付ける行為は二行目が相当するRubyには myobjectのようにオブジトそのものを表す変数は存在しない*

書いてて思ったポインタ(に近いもの参照C++の参照とは違うもの)はスクリト言語では普通に使われている*4Rubyでは C++myobjectに相当するものがなく全てのオブジトが一段遠くにあるからC++でやるように (*pmyobject).hoge()pmyobject->hoge() というようにポインタをデリファレスする手間を省いて myobject.hoge() という書き方でメソドを呼べるがRubymyobjectC++myobjectよりむしろポインタの pmyobjectに一番近い

* Fixnumは例外

 これが Ruby++--が存在しない理由かとも思ったがC++で単項インクリメ/デクリメトをメンバ関数でオーバーロドできることを考えると Rubyでやっていけない理由がわからないRubyでも ++相当のメソドを定義できるということだし全てがオブジ(内部状態を持てる)であることを謳っている Rubyだからこそ制約なしにやっても構わないんじhttp://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/5323

 いやいやいや仮に ++/--というメッセージが追加されても Numericはイミータブルだという理由で使えなければ 99%の利用場面が奪われるこれをなんとかすると +++=のシンタックスシュガーになったりFixnumがオブジトでない(=変数がオブジトへの参照でない)ことが露呈したりa=b=1; ++b;a2 になったりするこれは違う

*4 C++&のような明示的にスを取得する方法がないのでポインタのポインタは存在しない


20080317() Google(jp)経由でこの日記を初めて見つけた (SHJSで検索30件表示してると 1ージ目()検索しても見つけられないレアなサトだったのに……っと客観視してみるとえらく解りにくく読みにくい文章を書いていた

[Ruby] RUBY_INSTALL_NAMEruby以外に変更してもイールできるようになってる (Ruby1.9)

win32/configure.batが生成する Makefileを編集して* ruby19.exeを作るようにしていると ruby-dev:34000 と同じところで止まっていたのでした

MLのスレドを読んでRUBY_SUFFIXだけでなく RUBY_INSTALL_NAMEも反映して欲しいと思ったらそのように変更されてコミトされていたそれは手元の Makefile.subと同じです。

* configure.batの引数として与える方が人手を介さない分良さそう1.8のときに prefixオプションが効かなくて Makefileの直編集に切り替えたのだった気がするが1.9.0-1では効いていたと思う(最初いつも通りにしたら C:/Program Files (x86)/ruby/Program Files (x86)/rubyにイールされたのはprefix=PREFIX=が両方有効だったからだと思う)


20080307() 紅玉 = 赤い宝石 = Rubyったのねん紅玉制覇編の意味が今わかった最近名前に意味がある意味を込めようとする人が多いということに気付いてきている(でもこれは単なる語彙の問)

[Ruby] Ruby-1.9.0-1: NMAKE : fatal error U1045: spawn failed : No error Stop.

miniruby.exeを作るところとruby.exerubyw.exeを作るところで止まる何度でも止まる

nmake/N オプションで実行されるコマドを表示して自分でタイプ*実行すると進むから不思議

* 嘘手打ちじゃない


20080304() 現在 9Fトカゲを倒す必要がないことにしばらく気付かなかったよ

最終更: 2010-03-22T05:44+0900

[][][Ruby][単行] artonRuby256倍使うための本 邪道編】 アスキ

著者は ActiveScriptRubyarton

この本が出た当時、Mysterious SyndromeWindows Scripting Host Laboratoryの管理人むたぐち氏が言語は RubyであるがCOMWSHの話題は VBScriptJScriptと共通だし他にこんなに突っ込んだ類書もないので(言葉と内容は全然違うが)自身の掲示板でおすすめされていたのをずっと覚えている

タイミングを逸していただけなのだ

Rubyの名前を初めて目にしたのもこの時だったかもしれない(「何か(当時)の名前を目にしたのもこの掲示板が……美耳いいよ)

あくまで目にしていただけで初めての CGIプログラムはサンプルの多い Perlで書いたしすぐに嫌気がさして代わりの言語を探したときに Ruby""発見しているそのときにWSHに親しんでいたことと ActiveScriptRubyの存在が Ruby採用のきっかけになったというのは多分にありそう

思い出深い一冊ということこの本を通して気付かないまま Rubyとすれ違っていたのだから


20080213() ァイルを編集していつものように Subversionにコミトしたら http越しに http://hikidoc.rubyforge.org にコミトしにいっていた拒否されて本当に良かったこういうときは SVKMercurialですか?

[Hiki][Ruby] HikiDoc(revision 90)のリトアイムに段落を

トを使うと途端にそこから文章に構造がなくなってしまうのが困りものでできるだけ !!(h4)!!!(h5)を使うようにしていたのだけどとうとうリトアイム内で段落を書けるようにいじってしまった(少し前の変更で取り除かれた \ エスケープが復活している…)

 hikidoc.rb.extend-listitem.diff (2.4KiB)

HikiDoc(r90)のリトアイムに文章構造(段落)を持ち込むための変更

 HikiDocーマ

*li1-p1\
\
li1-p2A\
li1-p2B
*li2

 HTML

  • li1-p1

    li1-p2A li1-p2B

  • li2

 HTMLース

<ul>
<li><p>li1-p1</p>
<p>li1-p2A
li1-p2B</p>
</li>
<li>li2</li>
</ul>
  • 影響を最小限にするために \を使って行をまたいだときだけ <p>タグが挿入される
  • 段落以外の実はすべてのマークアップが有効になっているがどういう表示になるかは未確認
  • 思いつきのやっつけです。

行末の \ は見落としやすいので *-**-***-前行のリトアイムを継続するという意味にするのはどうだろう

 hikidoc.rb.extend-listitem2.diff (1.6KiB)

HikiDoc(r90)のリトアイムに文章構造(段落)を持ち込むための変更2 (以前の変更からの差分なので順番に適用する必要がある)

 HikiDocーマ

* li1-p1
*-
*-li1-p2A
*-li1-p2B
*li2

 HTML

  • li1-p1

    li1-p2A li1-p2B

  • li2

 HTMLース

<ul>
<li><p>li1-p1</p>
<p>li1-p2A
li1-p2B</p>
</li>
<li>li2</li>
</ul>

なぜ *+ でなく *- にしたんだろう……

[Ruby] Ruby-1.9の文字コド関連

面倒くさいという印象しか持っていない

文字コドに unawareなスクリトが文字コドがらみで余計なことをされたあげく動かなくなるというのだけはやめてほしい

必要なときだけエンコング情報を付加するしそのときだけエンコング情報を利用したメリトを受け取りたい

実際のところはどうなってるのでしょう


20080111() 文字クラス内で後方参照は使えない/(")[^\1]*\1/ のようなものは [^1]とも [^"]のときとも違う結果になった(Ruby1.8, JScript, JavaScript(Fx3rc1)で実)

最終更: 2016-11-12T11:41+0900

[正規表現][Ruby] 鬼車すごい正規表現で再帰ができる

Ruby括弧を使った %記法だって

irb19> re = /%[Qq]?(?<brace>\{[^\{}]*(?:\g<brace>[^\{}]*)*})/
irb19> strings = %w(%{z}a %{a{b}z}c %{a{b}c{d{e}f}z}g %{{{{}}}z}a %{a{b}c %{z}a}b)
irb19> strings.each{|str| p str[re] }
"%{z}"
"%{a{b}z}"
"%{a{b}c{d{e}f}z}"
"%{{{{}}}z}"
nil
"%{z}"
=> ["%{z}a", "%{a{b}z}c", "%{a{b}c{d{e}f}z}g", "%{{{{}}}z}a", "%{a{b}c", "%{z}a}b"]

どの例も正しい範囲( %{ から z} まで)を切り取っているのがわかる

  1. この機能が使える鬼車がのってる Ruby1.9.0
  2. PCRE(ver 4.x)(?P<name>...)(?P>name)が同じものにあたるらしいそんなものjavascript(JScript)の正規表現も新しくならんかな
  3. .NET(?<open>...)(?<close-open>...)も同じことができるらしいが正直わからん*
  4. http://www.kt.rim.or.jp/~kbk/regex/regex.html < 正規表現の各種実装の違いがよくわかる

 追記@2008-05-09: 対応する括弧にマッチする正規表現のヴァリエイション(<くどい表記だ)

/%[Qq]?(?<brace>\{(?:[^\{}]++|\g<brace>)*})/

若干速い同じパターン( [^\{}] )の繰り返しも存在しない。http://fleur.hio.jp/perldoc/perl/5.10.0/pod/perl5100delta.mix.html#Regular_expressions を参考にした

/%[Qq]?(?<brace>\{(?:[^\{}]+|\g<brace>)*})/

上のものの + が一つ落ちたもの開き括弧が余分にある文字列を食わせると待てども待てども返ってこない http://mlog.euqset.org/archives/ruby-list/42232.html で既に書かれているそれに対する返答が http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/42233

* http://msdn2.microsoft.com/ja-jp/library/bs2twtah(VS.80).aspx#BalancingGroupDefinitionExample

 \1 (後方参照)単純にすでに出現したのと同じ文字列にマッチするパターンなのに対して任意のパターンを指定できるものだと想像してみる

 追記@2008-05-09: それでは括弧のネトに対応できないそれは条件分岐の一形態.NETのものはカウンタの増減を指示する構文

最終更: 2016-11-12T11:41+0900

[SakuraEditor][Ruby] SakuraEditor正規表現キーワドファイル(Ruby)を作っていた

テキトエタはメモ帳TeraPadときて現在は SakuraEditorもう五年以上使っているxyzzy(正式な読み方はないらしいと読んでいるsaxyunの読みがサッキュンなのは詐欺だと思います)Meadowに移る気は無し

構文ハイラトには興味がなくてどこかからダウンロドしてきた強調キーワドファイルや正規表現キーワドファイルを使っていた間違いがあっても正規表現を直したりはせずオフにするだ邪魔にならなければいい程度の扱いだった

ところが最近 SHJSをいじってたこともあって中途半端なハイラトが許せなくなってしまった

 SHJS+ブラウザと同じ表示を SakuraEditorでも!

そのためには鬼車が必要BREGEXP.dllでは %Q<a<b<c>d<e>f>g> のように入れ子になった括弧の対応を調べられないので

 前提条件
 Rubyーワドファイル(ruby_keywords.zip)をダウンロドしてエタでインポ

ーワドファイルはこの日記の SHJS(with カスタマイズ版 sh_ruby.js)を使ったハイラトとコンパチただし完全移植ではないサクラエタの正規表現キーワドは正規表現一発でッチした全体を特定の配色にするだけだけどSHJSはパターン中のキャプチャグループごとに配色を分けることができるサクラエタの制限で正規表現が行をまたいでマッチできないことも影響がある正規表現マッチが行をまたげないのは SHJSも同じなのだがSHJSは正規表現キーワドから利用できるスタックを用意していて行を超えて色指定を継続できる


20080101() Application Dataなんてフォルダを掘って一人で中に収まってる Operaは恥を知れ (Vistaでの)

[SHJS][Ruby][tDiary] SHJSRubyールを修正(sh_ruby.js, sh_ruby.min.js)

以下変更点のリ(\bの使い方が適当なのでスペースの少ないソースで問題が出る可能性あり\bの使いどころが全然わかってないせ)

    { // part of Kernel methods.
      'regex': /\b(?:defined\?|Array|Floar|Integer|String|abort|callcc|exec|exit!?|fork|proc|lambda|set_trace_func|spawn|syscall|system|trace_var|trap|untrace_var|warn)\b/g,
      'style': 'sh_preproc'
    },

なくてもいいかなと思うけど defined?Kernelモジールのメソドの一部を sh_preprocとして追加Rubysh_preprocなのは requireだけなので sh_preprocの配色を流用した選んだのは abortcallccexitforksystemなど比較的重要そうなもの(loopなど一部の他のメソドは sh_keywordとして既に分類されてい)

    {
      'next': 4,
      'regex': /<(?=[\w\/])/g,
      'style': 'sh_string'
    },

正規表現を /</g から変更<<メソドやヒドキュメ(<<HOGE)にマッチしないように

    { // Symbol
      'regex': /:(?:(?:@@|@|\$)?\w+[\?!]?|\+=?|!=?|~|\*\*=?|-=?|\*=?|\/=?|%=?|<<=?|>>=?|&=?|\|=?|^=?|>=?|<=?|<=>|===?|=~|!~|&&=?|\|\|=?|\.\.|\.\.\.|=)(?=\s|$)/g,
      'style': 'sh_string'
    },

新ルールシンボル(:hoge)sh_stringとして色付

    { // %!string!
      'regex': /%[Qq]?([!-'*-\/:;=?^]).*?\1/g,
      'style': 'sh_string'
    },

新ルール%!string!%Q!string!%q!string!sh_stringとして色付残念ながら %Q[]のように括弧を使ったものは入れ子になった括弧を数えられないので非対応対応した詳しくは下の方

    {
      'regex': /(?:\b(?:alias|begin|BEGIN|at_exit|break|case|do|else|elsif|end|END|ensure|for|if|in|include|loop|next|raise|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield|and|not|or|def|class|module|catch|fail|load|throw)\b|&&|\|\|)/g,
      'style': 'sh_keyword'
    },

ここにはプログラムの流れや定義に関するキーワドや Kernelメソドが集められているようなので既に登録されている ENDと同じ働きの at_exitを追加しdefinedを削除(上で sh_preprocとして defined?を登録済み)falsenilselftrue__FILE____LINE__を削除しあとで定数として定義&&||andorに対応するものとして追加

    { // global variables
      'regex': /\$(?:[_&~`'\+\?!@=\/\\,;\.<>\*\$:"]|-?[A-Za-z0-9_]+)/g,
      'style': 'sh_type'
    },

グローバル変数の定義を追加sh_typeはイスタス変数やクラス変数のクラス名として使用されているもの

    { // Constants
      'regex': /\b[A-Z]\w+[!\?]?(?=\b|$)/g,
      'style': 'sh_function'
    },
    { // Constants
      'regex': /\b(?:false|nil(?!\?)|true|self|__FILE__|__LINE__)(?=\b|$)/g,
      'style': 'sh_function'
    },

定数のルールを追加sh_functionRubyでは使われていないクラス

    {
      'regex': /[a-z0-9_]+(?:\?|!)/g,
      'style': 'sh_normal'
    },

正規表現を /[A-Za-z0-9_]+(?:\?|!)/g から変更定数は区別したいじゃない

 余談

    {
      'exit': true,
      'regex': /$/g
    },

文字列リテラルの終了条件に上のは必要ないむしろこれがあることで複数行にまたがったリテラルを正しく認識できないのだけど強力すぎる正規表現は誤認識があったときにソースを最後まで一色に染めてしまう危険性があるのでそのままにしているドキュメトに対応しないのも同じ理由

 追記@2008-01-02括弧を使ったリテラルにも対応した

    { // %r(regexp)
      'next': 6,
      'regex': /%r[\(<\[\{]/g,
      'style': 'sh_regexp'
    },
    { // %x(command), %w(array)
      'next': 7,
      'regex': /%[xWw][\(<\[\{]/g,
      'style': 'sh_normal'
    },
    { // %(string)
      'next': 8,
      'regex': /%[Qq]?[\(<\[\{]/g,
      'style': 'sh_string'
    },
  [
    {
      'exit': true,
      'regex': /$/g
    },
    {
      'next': 6,
      'regex': /[\(<\[\{]/g,
      'style': 'sh_regexp'
    },
    {
      'exit': true,
      'regex': /[)>\]}]/g
    }
  ],
  [
    {
      'exit': true,
      'regex': /$/g
    },
    {
      'next': 7,
      'regex': /[\(<\[\{]/g,
      'style': 'sh_normal'
    },
    {
      'exit': true,
      'regex': /[)>\]}]/g
    }
  ],
  [
    {
      'exit': true,
      'regex': /$/g
    },
    {
      'next': 8,
      'regex': /[\(<\[\{]/g,
      'style': 'sh_string'
    },
    {
      'exit': true,
      'regex': /[)>\]}]/g
    }
  ],

括弧の対応をチックすることはするけどカッコの種類を区別しないので

%(foo{bar)baz}

こんなのも通る。でも現実的には区別する必要ないよねHTML断片を組み立てるときに問題がありそうそしてそういうときにこそダブルクーテーションを使わずに %[]を使うんだよね試してみる

html << %[<option value="#{h hoge}"] << (selected? ? ' selected="selected">' : '>') << h(hoge) << "</option>\n";

っぱりダメだ〜

 追記@2008-01-02括弧を使ったリテラルに正式に対応した

上で出し「こんなのも通る」と「やっぱりダメだ〜の例が言葉とは裏腹「通ってない」と「ちゃんとできてる状態になってると思うだとしたら成功

変更点は20080102p01

 追記@2008-01-05#コメトと #{interpolation}の順番を入れ替え

# for variable interpolation, #{ is not a comment

というコメトを付けて #{}のハイラトルールを定義しているにも関わらずそれが #コメトルール よりも後ろにあるために機能していなかった#コメトルールを後ろに持ってきて解決

続きは20080105p01


20071231()

[tDiary][Ruby] evalは最終手段*module ::TDiaryを使うんだ

 plugin/counter.rb

 plugin/disp_referer.rb

 plugin/makelirs.rb

 plugin/makerss.rb

 plugin/navi_user.rb

 plugin/pb-show.rb

 plugin/recent_list.rb

 plugin/tb-show.rb

 plugin/title_tag.rb

eval(<<__END_OF_TOPLEVEL__,TOPLEVEL_BINDING)
module TDiary
end
__END_OF_TOPLEVEL__

に類する eval

module ::TDiary
end

でいいじゃない

 tdiary/defaultio.rb

(行間に構造に関係しないコドが省略されていま)

module TDiary
	class DefaultIO < IOBase
	private
		def restore( fh, diaries )
						diary = eval( "#{style( style_name )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )

最後の行はこれ↓で

						diary = style( style_name )::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )

 tdiary.rb

 plugin\pingback\pb.rb

anchor_str = @plugin.instance_eval( %Q[anchor "#{@diary.date.strftime('%Y%m%d')}"].untaint )

anchor_str = @plugin.anchor( @diary.date.strftime('%Y%m%d' ) ).untaint

OK


あえて寝た子を起こすまねをして新たなエラーを引き起こすこともないとは思うけど……とはいえ

@plugin_files.grep(/\/category.rb$/).empty?

のコピペの連鎖のようなものは断ち切りたいemptyかどうかを知りたいのならマッチする全ての要素を集めてくる必要はなくて

not @plugin_files.any?{|pi| /\/category.rb\z/ =~ pi }
@plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil?

のどちらかで十分です。速度的なもの(なんという婉曲さw)は計ってないけどcategory.rbcで始まるから (有効になっているのな) @plugin_filesの最初の方にあってすぐに結果がでるもののはず。

 ってみたよ

irb(main):044:0> plugin_files = Dir.glob('./*.rb')
=> ["./a.rb", "./akismet.rb", "./amazon.rb", "./append-css.rb", "./bq.rb", "./calendar2.rb", "./calendar3.rb", "./category.rb", "./comment_mail-qmail.rb", "./comment_mail-sendmail.rb", "./comment_mail-smtp.rb", "./comment_rank.rb", "./counter.rb", "./daily_theme.rb", "./disp_referrer.rb", "./doctype-html401tr.rb", "./dropdown_calendar.rb", "./edit_today.rb", "./footnote.rb", "./gradation.rb", "./gradient.rb", "./hide-mail-field.rb", "./highlight.rb", "./html_anchor.rb", "./image.rb", "./kw.rb", "./list.rb", "./makelirs.rb", "./makerss.rb", "./my-ex.rb", "./my-sequel.rb", "./navi_user.rb", "./number_anchor.rb", "./pb-show.rb", "./ping.rb", "./pingback.rb", "./random_google.rb", "./recent_comment.rb", "./recent_comment3.rb", "./recent_list.rb", "./recent_namazu.rb", "./recent_rss.rb", "./recent_trackback3.rb", "./referer-antibot.rb", "./referer-utf8.rb", "./referer_scheme.rb", "./search_control.rb", "./search_form.rb", "./sn.rb", "./speed_comment.rb", "./squeeze.rb", "./src.rb", "./tb-send.rb", "./tb-show.rb", "./title_list.rb", "./title_tag.rb", "./tlink.rb", "./todo.rb", "./weather.rb", "./whatsnew.rb", "./xmlrpc.rb"]
irb(main):045:0> Benchmark.bmbm{|j|
irb(main):046:1* j.report('grep'){ 10000.times{ plugin_files.grep(/\/category.rb$/).empty? } }
irb(main):047:1> j.report('grep2'){ 10000.times{ plugin_files.grep(/\/category.rb\z/).empty? } }
irb(main):048:1> j.report('any?'){ 10000.times{ not plugin_files.any?{|pi| /\/category.rb\z/ =~ pi } } }
irb(main):049:1> j.report('find'){ 10000.times{ plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil? } }
irb(main):050:1> }
Rehearsal -----------------------------------------
grep    0.359000   0.000000   0.359000 (  0.361000)
grep2   0.297000   0.000000   0.297000 (  0.275000)
any?    0.109000   0.000000   0.109000 (  0.104000)
find    0.094000   0.000000   0.094000 (  0.105000)
-------------------------------- total: 0.859000sec

            user     system      total        real
grep    0.297000   0.000000   0.297000 (  0.270000)
grep2   0.281000   0.000000   0.281000 (  0.275000)
any?    0.094000   0.000000   0.094000 (  0.100000)
find    0.140000   0.000000   0.140000 (  0.101000)

最新のプラグイン集のプラグインを全て有効にしたのと同じ状態では any?findの勝ちこれでは全ての要素を調べる grepがあまりに不利(ちなみに category.rbが見つからなくて grep同様に配列の最後まで調べた場合any?findgrepの二倍強の時間がかかっていたyieldがあるからな)

plugin_filesの要素数を半分の 30にしても any?findの勝ちだったので有効なプラグイン数15(category.rbを含む)の状態でもう一度

irb(main):058:0> plugin_files = plugin_files[0,15]
=> ["./a.rb", "./akismet.rb", "./amazon.rb", "./append-css.rb", "./bq.rb", "./calendar2.rb", "./calendar3.rb", "./category.rb", "./comment_mail-qmail.rb", "./comment_mail-sendmail.rb", "./comment_mail-smtp.rb", "./comment_rank.rb", "./counter.rb", "./daily_theme.rb", "./disp_referrer.rb"]
irb(main):059:0> Benchmark.bmbm{|j|
irb(main):060:1* j.report('grep'){ 10000.times{ plugin_files.grep(/\/category.rb$/).empty? } }
irb(main):061:1> j.report('grep2'){ 10000.times{ plugin_files.grep(/\/category.rb\z/).empty? } }
irb(main):062:1> j.report('any?'){ 10000.times{ not plugin_files.any?{|pi| /\/category.rb\z/ =~ pi } } }
irb(main):063:1> j.report('find'){ 10000.times{ plugin_files.find{|pi| /\/category.rb\z/ =~ pi }.nil? } }
irb(main):064:1> }
Rehearsal -----------------------------------------
grep    0.188000   0.000000   0.188000 (  0.175000)
grep2   0.109000   0.000000   0.109000 (  0.099000)
any?    0.110000   0.000000   0.110000 (  0.106000)
find    0.109000   0.000000   0.109000 (  0.107000)
-------------------------------- total: 0.516000sec

            user     system      total        real
grep    0.125000   0.000000   0.125000 (  0.096000)
grep2   0.094000   0.000000   0.094000 (  0.094000)
any?    0.110000   0.000000   0.110000 (  0.101000)
find    0.125000   0.000000   0.125000 (  0.105000)

category.rbを含めて 15のプラグインが有効の場合僅差で any?findの負category.rbを使ってない場合any?findはさらに不利になるわけだけど……(みんな使ってるよね) この日記では category.rbを含めて 23(+必ず有効な4)のプラグインが有効だから any?findがもう少し有利になって結論「どっちでもいいけどそれなら findを使うプラグインは増やすことはできても減らすと過去の日記でエラーが出たりするから

 追記@2008-01-06grepは名前勝ち?

なじみがあって処理内容が明確だから使いやすいのかも同じことを find_allでやろうとするよりも(any?findの結果から考えて)倍近く高速だろうことも想像ができるので使いどころが正しければ優秀なメソ

 追記@2008-01-06ブロック付き Enumerable#any?(all?)Ruby 1.8 feature

2.2.0までは Ruby 1.6もサポトしていたので any?の使用は考えられないのだったでも findRuby 1.6からあるようなのでここまで書いたことが全否定されたというわけでもないよかった

* ほんとうに?なんで?


20071225() なんでもかんで「相性で片付けて原因究明を怠る(一部の)風潮が嫌い

[Ruby][tDiary] PStore, category.rb: 日記に変更があるたびにカテゴリキッシュファイルが一斉に更新されるのをなんとかする

日記を更新するとTDiary::Config#data_path/category/ 以下のカテゴリごとに作られるキッシュファイルがずいぶんたくさん更新される全部ではないが半分近い 21のファイルが更新されていた日記の内容はというと一つのカテゴリしか使っていない

どこのコドが無駄にファイルを更新しているのかと絞っていくとcategory.rbの中の Category::Cache#replace_sectionsだとわかったではこの replace_sectionsが悪いのかというとそうではないreplace_sectionsの中の

PStore.new(cache_file(c)).transaction do |db|
end

に囲まれた部分をすべてコメトアトしても 21のキッシュファイルが一斉に更新されたのだから一部の PStoreァイルは開いて閉じるだけで常に更新されるのだとしか考えられない

PStoretransactionの前後で Marshal::dump の戻り値のサイズと MD5が変化したかどうかを見て変更があったかどうかを判断しァイルに書き込みをするかしないかを決めているMarshal::load/dump が対称ではないのだろ(そもそも HashMarshal::dumpした結果が一定だと仮定してよいのだろうか*)

原因が何であるにせよサーバーの pstore.rbを書き換えるわけにもいかないのでtDiarycategory.rbに対策を施した

 PStore#transaction(true)を使う

読み出し専用であることが予めわかっている PStore#transactionはすべて trueを引数にして(readonly=trueの意)呼び出す。実はそういう transactionはすべて PStore#abortで終わっているのでこの対策は必要ないのだがァイルを排他ロックすることと MD5を計算する手間が省けるので一応

 PStore#abortを使う

肝心の Category::Cache#replace_sectionstransactionの開始前に変更があるのかどうかがわからないので PStore#transaction(true)は使えない日付の削除が空振りに終わったときにだけ PStore#abortを呼ぶことにするこれで必要最低限のキッシュファイルだけが更新されるようになった

	#
	# cache each section of diary
	# used in update_proc
	#
	def replace_sections(diary)
		return if diary.nil? or !diary.categorizable?

		categorized = categorize_diary(diary)
		categories = restore_categories
		deleted = []
		ymd = diary.date.strftime('%Y%m%d')

		categories.each do |c|
			PStore.new(cache_file(c)).transaction do |db|
				db['category'] = {} unless db.root?('category')
				if categorized[c] and diary.visible?
					db['category'].update(categorized[c])
				else
					# diary is invisible or sections of this category is deleted
					db.abort unless db['category'].delete(ymd)
					deleted << c if db['category'].empty?
				end
			end
		end

		if !deleted.empty?
			deleted.each do |c|
				File.unlink(cache_file(c))
			end
			replace_categories(categories - deleted)
		end
	end

* 追記:最近の Ruby(1.8.7だか 1.9.0)Hashkeyの順序を保存しているみたいだけど


20071220()

[Ruby] るびまゴルフ 【第 2 回】

 問題

以下のコドと同じ出力をより短いコドで得よ(ーは 27)

-2000.step(-10000,-10) do |v|
  puts v
end

 答案

n=1990;801.times{p -n+=10}

-1 (26)だからバーかなアルトロス(-3)が上限とは限らないけど数値リテラルが冗長な気がするけど他の表現が思いつかない文字コ(?X)を使おうと思ったけどできなかった

 ってみたこと

  • 省ける空白を省く
  • doend{}
  • putsp
  • 三カ所の -(マイナス)を一カ所に

 失敗したこと

  • ブロック変数名を $\(レコドセパレータ)にしてprintを無引数で呼ぶ(.step{|$\\|print}$\に数字を代入できなくて失敗なら文字列に対して uptoを呼べばいいんだけど文字列リテラルにするために引用符で +2ト使っちゃ無駄が多いしそもそもお題を満たせないし)
  • (irb限定) 変数_を使ったインチキ

 できなかったこと (他人の答えを見)

  • 三カ所の 0()を一カ所に (思いつかなか)
  • Shift_JISの文字コドを利用 (できなか)

20071217()

[Ruby] Rubyの 定数の見える範囲 の理解はあきらめております

irb(main):115:0> require :benchmark.to_s
irb(main):119:0> Benchmark.bmbm{|j| j.report }
NameError: uninitialized constant Benchmark::Job::ArgmentError
        from C:/Program Files (x86)/ruby/lib/ruby/1.8/benchmark.rb:333:in `report'
        from (irb):119
        from C:/Program Files (x86)/ruby/lib/ruby/1.8/benchmark.rb:250:in `bmbm'
        from (irb):119
        from :0
irb(main):120:0>

 追記@2008-02-20実は可視範囲の問題ではなくタイポだった

ArgmentError -> ArgumentError

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/44601


20070129()

[Ruby] 文字列リテラル連結

irb(main):001:0> RUBY_RELEASE_DATE
=> "2006-12-25"
irb(main):002:0> "aaa"\
irb(main):003:0* "bbb"
=> "aaabbb"
irb(main):004:0> "aaa"\
irb(main):005:0* %[bbb]
NameError: undefined local variable or method `bbb' for main:Object
        from (irb):5

こういうもんなの? "bbb"%!bbb! は同じものだと思っていた

 記:2007-12-12

'%04d-%02d-%02d'%[2007,12,12]
=> "2007-12-12"

String#% が呼ばれてるんだよ