「折りたためる」「立体」…。これは……、と読んでみれば果たして「建築家阿竹(あたけ)克人さん(56)が開発した」とあった。
なんでそんな連想が働いたかといえば数日前に読んだこの本。
試してみた。SecurityErrorが出た。リンク先の ruby-1.9.1とは違い、こちらは ruby-1.8.7-p72でのエラー内容。
>irb irb(main):001:0> require 'open-uri' => true irb(main):002:0> $SAFE=1 => 1 irb(main):003:0> open 'http://vvvvvv.sn25p.dip.jp/301.rb' SecurityError: Insecure operation - [] from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:577:in `[]' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:577:in `find_proxy' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:147:in `open_loop' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:164:in `call' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:164:in `open_loop' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:162:in `catch' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:162:in `open_loop' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:132:in `open_uri' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:518:in `open' from C:/Program Files (x86)/ruby/lib/ruby/1.8/open-uri.rb:30:in `open' from (irb):3 irb(main):004:0>
301.rbはこう。
#!ruby require 'cgi' cgi = CGI.new; print cgi.header({ 'Status' => '301 Moved Permanently', 'Location' => 'http://vvvvvv.sn25p.dip.jp/index.html' });
ホストネームを指定しない場合は大丈夫だった。例えばこんな。
#!ruby require 'cgi' cgi = CGI.new; print cgi.header({ 'Status' => '301 Moved Permanently', 'Location' => '/index.html' });
どこまで by designなんだろう。
過去にこんなことを書いた。
過去の日記を「編集」するとその日の全てのセクションが rdfに上ってくるのね。tDiary-2.3系の目玉はセクション単位での編集機能だなあ。
セクション単位の編集機能を実装しおえて、makerss.rbの対応もやっとくか、とソースを読んでみたらきっちり内容比較をしていた。だから当然、変更されたセクションのみが RSSで上に上がってくる。一文字も変更せずに日記を送信した場合、RSSも更新されない。ローカルの tDiaryで確認した。でもサーバー( http://vvvvvv.sakura.ne.jp/ds14050/diary/ )ではそうなっていない。過去に書いたとおり、どんな場合でもその日のすべてのセクションが上がってくる。
そういえばこんなこともあった。
日記を更新すると、TDiary::Config#data_path/category/ 以下の、カテゴリごとに作られるキャッシュファイルがずいぶんたくさん更新される。全部ではないが半分近い 21のファイルが更新されていた。日記の内容はというと一つのカテゴリしか使っていない。
根が同じかどうかはわからないが、なにかがおかしい。
そういえば、makerss.rbの作成するキャッシュファイルもカテゴリインデックスと同じ PStore形式だった。におう、におうぞ。
必ずしも上がってくるというものでもないみたい。サーバーの makerss.rbも概ね期待通りの動作をしている。うにゅう。
あまりに古い日記を編集していて、makerss.cacheから記事が掃き出されているために変更の有無を確認できない、というのとも違うんだけど。……と思うんだけど。(もういいや)
とりあえず内容を比較する前に stripしてみた。これで様子見。(複数のエントリが同じ時刻に更新されたかのように記録されることがなくなければ O.K.)
if cache[id].section.body_to_html.strip != section.body_to_html.strip or cache[id].section.subtitle_to_html.strip != section.subtitle_to_html.strip then cache[id] = RDFSection::new( id, Time::now, section ) end
最終更新: 2009-12-10T00:55+0900
ルールを守るために未来日記を書く人もいるようですが、これはあくまで普通の日記だし、書いた日付と内容は切り離せないので、一日に複数のエントリを書いたりもします。だから、セクション単位での編集機能を、もちろんブラウザで。
編集画面 | プレビュー画面 | プレビュー画面(競合あり) | 登録画面(競合あり) |
---|---|---|---|
変更内容はこのような感じ。
例えば、2009年2月26日の第1セクションの編集フォームへのリンクはこうなる。
update.rb?edit=1;year=2009;month=2;day=26;section=1
現在編集中のセクションが他の人によって書き換えられていたり、セクションの挿入や削除によってセクションナンバーが変わっていたときは、エラーメッセージを表示して(プレビュー画面でも確認可能)、変更をコミットしない。(「戻る」の後でも直前の編集内容が残っているかどうかは使用しているブラウザ次第)
従来の一日単位での編集では失われていた*著者情報が、セクション単位の編集では保存される。(編集対象のセクションは一番最後の変更者名になる)
ついでに、ある日の編集フォームを利用して、別の日に追記したとき――編集画面で日付を書きかえた後、この日付の日記を編集ボタンを押さずに、登録ボタンを押すことで可能――、記録されていなかった*著者名も記録する。
というわけで、skel/update.rhtml.zhと skel/preview.rhtml.zhは手つかずなので、従来の編集画面と機能になる。
skel/update.rhtml.enと skel/preview.rhtml.enは書きかえたけど動作未確認。
とはいえ、スタイル関連で利用するメソッドは each_section、append、replaceだけなので動くはず(期待)。
ただ、Diary#to_srcが Section#to_srcを単純に連結したものである、という仮定をおいてしまっているのだが、新旧wiki_style、rd_style、emptdiary_style、hatena_style、markdown_styleは大丈夫なものの、etdiary_styleは少しだけ違っているのが若干気になる。(といっても末尾の改行を一つにまとめてるだけなんだけど)
type="submit" name="edit"
上記が共通部分。(ボタンのラベルも送信されるけど、使われないので違ってて構わない)
新旧Wikiスタイルの場合、*.td2にはないよね。
tdiary_styleの場合、書き出される(TdiarySection#to_srcに含まれる)けど、読み込んだらカテゴリの一つになってしまいそう。
etdiary_styleも書き出すけど、読み込みは考えてなさそう。EtdiarySection#initializeに明示的に authorを渡しても使われない。
不毛だ。
プラグインの表示したフォームを送信すると、次の画面が普通の一日分の編集画面になる。<input type="hidden" name="date" value="yyyymmdd"> というようなフォームを埋め込む責任が個々のプラグインに委ねられているのでどうしようもない。
TODO: 元の画面に戻ることを保証することと、プレビュー画面に form_procを表示すること。
プレビュー画面への form_proc表示はもうやってるし、form_procを利用したファイルのアップロードを別タブの編集画面でやれば、変更内容が失われる心配もない。知ってるから困らないけど、わかりにくいのは確か。
一日表示のとき、セクションごとに編集リンクを付ける。
add_subtitle_proc {|date, section, subtitle| subtitle += %Q(<span class="adminmenu edit_section"><a href="#{h @conf.update}?edit=1;year=#{@date.year};month=#{@date.month};day=#{@date.day};section=#{section}" rel="nofollow">[edit]</a></span>); } if @mode == 'day';
サブタイトル(<h3>の中)に関係のないテキストを加えるより、サブタイトルの直前に挿入されるこっちの方がいいかも。
add_section_enter_proc {|date, section| %Q(<span class="adminmenu edit_section"><a href="#{h @conf.update}?edit=1;year=#{@date.year};month=#{@date.month};day=#{@date.day};section=#{section}" title="edit (author only)" rel="nofollow">✍</a></span>); } if @mode == 'day';
問題のコード(再掲)はこれ。あるハッシュのキーについて繰り返しているのに、ハッシュにそのキーが存在しない。(すべてのキーが見つからないわけではないが、見つからないキーはいつでも見つからない)
categorized.keys.each do |c| PStore.new(cache_file(c)).transaction do |db| categorized.fetch(c) #=> key not found (KeyError) db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
fetchをブロックの最初に持って行くと、そこではエラーにならない。
categorized.keys.each do |c| categorized.fetch(c) #=> O.K. PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
cache_file(c)の呼び出しが原因。その中でも includeしてある ERB::Utilの u()メソッドが核心。
categorized.keys.each do |c| ::ERB::Util.u(c) categorized.fetch(c) #=> key not found (KeyError) PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
引数にした文字列のエンコーディングが変わってしまっている。
categorized.keys.each do |c| enc1 = c.encoding; ::ERB::Util.u(c) enc2 = c.encoding categorized.fetch(c) { raise "#{enc1} #{enc2} #{::ERB.version}" } #=> UTF-8 ASCII-8BIT erb.rb [2.1.0 2009-01-11] (RuntimeError) PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
ERB::Util.url_encodeの定義を見ると、引数の文字列を dupした後にエンコーディングを変更しているにも関わらず、呼び出し元に影響を与えてしまっている。
def url_encode(s) s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) { sprintf("%%%02X", $&.unpack("C")[0]) } end alias u url_encode
そんなわけだから呼び出し側(category.rb)で
u( c.dup )
なんてやっても効果はなく、
u( ""+c )
あるいは
u( "#{c}" )
とやって初めて、今回の現象を回避することができた。
これは、文字列の複製を遅らせた結果、期せずしておこった現象にみえる。
バグのはずなんだけど、irbで再現しようと思ってもできないんだこれが。
http://redmine.ruby-lang.org/issues/show/1929
(ここに、見るべき場所を見つけることもできなかった人間がひとり)
* 正しくは ruby-1.9.2dev(2009-02-03)
トラックボールを買いましたから。もともとマウスの使用に熟達していなかったからか、不自由を感じる暇もなく移行完了。2005年12月1日に届いてから 3年と2か月、ほぼ毎日数時間ずつ使用してきたが、MX610よ、ネズミさんよ、さようなら。
12ボタン+ホイールを誇る MX610だったけど、4ボタンしかない TM-150でも、なければないで不自由はしていない。例えば
MX610のボタンに割り当てていたキー操作をキーボードで行っているだけなのでした。
MX610を使っていたときは全ての操作をマウスで、かつポインタの移動は最小で、を目標にしていたが、4ボタントラックボールでは従来の、ほとんどの操作をキーボードで、の基本姿勢に戻っている。キーボードでは全てを行えないから、切り替えコストを下げるためにトラックボールは左手で操作している(面倒だからボタン割り当ては右手用のままで)。
本当は全てキーボードで操作したいのだけど、ポインティングデバイスへの持ち替えを余儀なくされる(それもわりと頻度の高い)操作がある。
Firefoxの、フォーカス先を画面内の要素に限定する機能は document.commandDispatcherを操作するだけで実現できそうな雰囲気だけど(advanceFocus()と suppressFocusScroll)、userContent.jsは敷居が高い。advanceFocus()のロジックを書き換えてやろうかとも思ったが、Firefoxのビルドがこれまた更に難しい。デフォルトの動作でないのが信じられないぐらい、必要としている機能なんだけど。
地球温暖化問題に異議を唱える本、という認識を持っていた。読んでみたら確かにその通り。かといって化石燃料の消費を助長する内容でもない。環境問題が論じられるところに科学が存在しないことを憂えている。また、環境保護=善(無条件に実行すべきこと)でもなくて、デメリットやコストを考慮してメリットを上回ることを確かめなければいけない、とも(具体例は読んでください。フロンや DDTの使用禁止にも考慮すべきデメリットがあるそうです)。温暖化・環境問題を「常識」として知っている人は、バランスをとるために是非とも読むべき。
訳者あとがきに、関連する複数の書籍への言及がある。知ってる人は知っていることなんだろう。(待っていても、TVのニュースからでは絶対に聞けない意見だろうけど。あるいはこちらの方で、そういう、環境保護に異論を唱える人に対して、うさんくさい人(産業界のまわし者)フィルターをかけてしまって、耳を塞いでいた可能性もある)
読んでいて、少し前に読んだ[文庫] サイモン シン【宇宙創成〈上〉 (新潮文庫)】 新潮社を思い出した。こちらは宇宙論の歴史を題材に《科学的方法》の意義を啓蒙する本だった。奇しくも、クライトンの本にも引用と共にカール・セーガンの名前がでてくる。
この断片で理解してもらえるだろうか。
categorized.keys.each do |c| PStore.new(cache_file(c)).transaction do |db| categorized.fetch(c) #=> key not found (KeyError) db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
あるハッシュのキーについて繰り返しているのに、ハッシュにはそのキーが存在しないという、この不思議。
このとき、c は、
"\xE6\x9C\xAC\xE6\x97\xA5\xE3\x81\xAE\xE8\xB3\xBC\xE5\x85\xA5" ASCII-8BIT
ハッシュのキーリストとそのエンコーディングは、
"\xE6\x9C\xAC\xE6\x97\xA5\xE3\x81\xAE\xE8\xB3\xBC\xE5\x85\xA5" ASCII-8BIT "本" UTF-8 "マンガ" UTF-8 "雑誌" UTF-8
存在しているだろうに……。
さくらインターネット上で tDiary を ruby1.9.1-p0 で動かす - まちゅダイアリー(2009-02-19)(14:57現在、日別表示が不可能な状態。最新表示は可能)
* 正しくは ruby-1.9.2dev(2009-02-03)
最終更新: 2009-08-29T06:18+0900
> URI.escape("http://exmaple.com/foo bar?a=b=c;d=e#hoge#fuga") => "http://exmaple.com/foo%20bar?a=b=c;d=e%23hoge%23fuga"
URLをパーツに分解せずに gsub一発でエスケープ(エンコード)するなんて不可能だと思うのです。仮にそうまでしても、上の例のように、「#」が CGIパラメータとして受け渡されるように、「%23」にエンコードするべきか、URLを構成する fragmentを示す記号として、「#」のまま残すべきか、判断できない(でしょう?)。
できないことをできるかのように見せかけるより、できない(のでメソッドを提供しない)という方が親切だと思う。
JavaScriptの提供する encodeURIComponent(「/」も「?」も「#」も「=」もエンコードするメソッド)相当のメソッドがあれば、それで十分だと思うんだけど。
http://exmaple.com/foo bar/baz/
なんてのは不正な URLだから、どこにも存在しないのです。アドレスバーに表示するときに人間に読みやすいように、と上のようにデコードして表示することはあるかもしれないけれど、オリジナルの正しい URLは同時に保持しておくべきで、表示用の文字列からエンコードしようなんて思っちゃダメなのです。ブラウザのアドレスバーは表示と同時に編集も可能だから話は簡単ではないけど……これまでのところ、Firefoxは(自らの責任で)よきに計らってくれています。
RFC(古いのと新しいのと二種類?)も読んでいない放言なので、実は「できる」という可能性がなきにしもあらず。
[ruby-dev:39188] Re: URI.escape_component から、
さておき、URI.escapeは独特の動きをするので、JavaScript/ECMAScript の escape とも encodeURI とも encodeURIComponent とも違います。 そういえば、現在の仕様の意図をお聞きしたかったんだった [ruby-dev:38124] なお、面倒な話が出てきた時には、とりあえず akr さんが 既に取り上げていないか調べるわけですが、やっぱり扱っているわけです。 http://www.a-k-r.org/d/d2004_07.html https://www.codeblog.org/blog/akr/20070222.html
手動で migrate.rbを実行して UTF-8化してあったのに、再度 90migrate.rbが走ってしまって、データが壊れた。慌てず ZIPファイルを解凍して元通り。
grepと同じ程度に簡単に、データファイルや tdiary.confのバージョンナンバーをすべて書き換える方法(sed?)が思いつかなかったので、tdiary/lang/ja.rbの migrate_to_utf8を無効化して済ませた。
def migrate_to_utf8( str ) return str to_native( str, 'EUC-JP' ) end
素通しとはいえ migrationは実行されるので、数十から百ちかい数のファイルを開いて書き込んで閉じてといった負荷をレンタルサーバーにかけた。ローカルでは一分以上かかった。
のが嬉しい。気になっていて、よっぽど自分でやってやろうかと思っていたので。
@accesskey_enabledの設定が存在しない(=>nil => falseと判断される)ために、アクセスキーがなくなってしまって戸惑った。ここはデフォルトを過去と互換にして欲しかった(設定名を @disable_accesskeyにするとか)。いまさらだけど。
NaviUserCGIが木偶だからだった。原因は category.rbにはなく、できの悪い CGIのモックを渡した navi_user.rbにある。
class Info include ERB::Util def initialize(cgi, years, conf, args = {}) @cgi = cgi @years = years @conf = conf @category = args[:category] || @cgi.params['category'] @year = args[:year] || @cgi.params['year'][0] #=> NoMethodError: undefined method `[]' for nil:NilClass
class NaviUserCGI attr_reader :params, :referer, :user_agent def initialize(datestr) @params = {'date' => [datestr]} # <<<注目! @referer = nil @user_agent = nil end def request_method 'GET' end end
オリジナルの CGI#paramsは単一のデフォルト値( [].freeze )を持った Hashなんだよね……。
navi_user.rbも recent_list.rbと同じように書き換えてやろうか。
* 一か所、大文字も小文字も存在しない配列のソートを普通のソートに戻しました。