NokogiriでXMLに子要素を追加すると要素名が小文字になる
解決
- Nokogiri::XML::DocumentFragment#newを使う。長ったらしくてめんどくさいし、もっといい方法がある気がするんだけど見つけられていない。
ソースコード
#!/usr/bin/env ruby # coding: utf-8 require "nokogiri" doc = Nokogiri::XML("<RootNode>") doc.root.add_child "<AddChildByString>" doc.root.add_child Nokogiri::XML::DocumentFragment.new(doc, '<AddChildByDocumentFragment>') puts doc.to_xml # => # <?xml version="1.0"?> # <RootNode> # <addchildbystring/> # <AddChildByDocumentFragment/> # </RootNode>
[追記 2013/03/07]Nokogiri::XML::Builderという便利なものがあった
Nokogiriのドキュメントを漁っていたら下記のような書き方で生成できることが分かった。こっちの方が便利そう。
#!/usr/bin/env ruby # coding: utf-8 require "nokogiri" document = Nokogiri::XML::Builder.new do |doc| doc.RootNode { doc.AddChildByString doc.AddChildByDocumentFragment } end puts document.to_xml
メソッド内でメソッドの引数の一覧を取得する
def hoge(a, b, c) p self.method(__callee__).parameters #=> [[:req, :a], [:req, :b], [:req, :c]] end hoge(1, 2, 3)
Kernel.#__callee__とMethod#parametersを使う。
__callee__で今いるメソッドの名前がSymbolとして取れるので、それをself.methodの引数に渡して、Method#parametersで引数の一覧を取得する、という流れ。
なんだか自分の好きな本を10冊挙げるのが流行ってるみたいなので流行に乗りました!!!
自分の好きな本を挙げるのがにわかに流行っているみたいなので。順番は思いついた順です。
- 作者: Alan Cooper,Robert Reimann,David Cronin,長尾高弘
- 出版社/メーカー: アスキー・メディアワークス
- 発売日: 2008/07/22
- メディア: 大型本
- 購入: 9人 クリック: 208回
- この商品を含むブログ (27件) を見る
- 作者: 高橋浩和,小田逸郎,山幡為佐久
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/11/18
- メディア: 単行本
- 購入: 14人 クリック: 197回
- この商品を含むブログ (118件) を見る
- 作者: まつもとゆきひろ,David Flanagan,卜部昌平(監訳),長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/01/26
- メディア: 大型本
- 購入: 21人 クリック: 356回
- この商品を含むブログ (129件) を見る
Metaprogramming Ruby: Program Like the Ruby Pros (Facets of Ruby)
- 作者: Paolo Perrotta
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2010/02/25
- メディア: ペーパーバック
- 購入: 1人 クリック: 14回
- この商品を含むブログ (4件) を見る
- 作者: Robin Williams,吉川典秀
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/11/19
- メディア: 単行本(ソフトカバー)
- 購入: 58人 クリック: 1,019回
- この商品を含むブログ (102件) を見る
誰のためのデザイン?―認知科学者のデザイン原論 (新曜社認知科学選書)
- 作者: ドナルド・A.ノーマン,D.A.ノーマン,野島久雄
- 出版社/メーカー: 新曜社
- 発売日: 1990/02/01
- メディア: 単行本
- 購入: 37人 クリック: 945回
- この商品を含むブログ (283件) を見る
フロー体験 喜びの現象学 (SEKAISHISO SEMINAR)
- 作者: M.チクセントミハイ,Mihaly Csikszentmihalyi,今村浩明
- 出版社/メーカー: 世界思想社
- 発売日: 1996/08/01
- メディア: 単行本
- 購入: 12人 クリック: 104回
- この商品を含むブログ (77件) を見る
JavaScript: The Definitive Guide: Activate Your Web Pages (Definitive Guides)
- 作者: David Flanagan
- 出版社/メーカー: O'Reilly Media
- 発売日: 2011/05/13
- メディア: ペーパーバック
- 購入: 1人 クリック: 151回
- この商品を含むブログ (3件) を見る
- 作者: Chad Fowler,でびあんぐる
- 出版社/メーカー: オーム社
- 発売日: 2010/02/26
- メディア: 単行本(ソフトカバー)
- 購入: 24人 クリック: 683回
- この商品を含むブログ (126件) を見る
- 作者: ドナルド・A.ノーマン,Donald A. Norman,岡本明,安村通晃,伊賀聡一郎,上野晶子
- 出版社/メーカー: 新曜社
- 発売日: 2004/10/15
- メディア: 単行本
- 購入: 3人 クリック: 132回
- この商品を含むブログ (58件) を見る
コマンドの処理が一定時間以上かかった時だけGrowlで通知する
~/.bashrcに書いておけば多分動く。bash以外で動くかは試してない。
Mac用に書いてるのでLinuxとかは適宜コマンドを(notify-sendとかに)置き換えてください。
function notify-last-command { # 3秒以上かかったらGrowlで通知する if [ 3 -lt $MYDATETIME ]; then growlnotify -n notify-last-command -t command -m "$( history 1 | awk '{s="";for(i=2;i<=NF;i++){s=s" "$i}print s}' )" fi MYDATETIME=0 } PROMPT_COMMAND='notify-last-command' MYDATETIME=0 function time_spent () { MYDATETIME=$(expr $(date +%s) - $MYDATETIME) } trap 'time_spent' DEBUG
仕組み
BashのPROMPT_COMMANDとtrapを利用している。
PROMPT_COMMANDに値を指定すると、プロンプトが表示される直前に指定した値がコマンドとして実行される。*1
trapは、本来はシグナルをトラップして色々処理するためのものらしいんだけど、上記のようにDEBUGを指定するとコマンドを入力してエンターを押した直後とPROMPT_COMMANDの直前で実行されるようなので今回はそれを利用している。*2
動作の順番としては、以下のようになっている。
作った理由
MacPortsのアップデートのような時間がかかる処理を終わったかどうかいちいちチェックするの面倒だし終わったら通知してほしい、みたいな感じです。
はてなブックマークはメニューをmap要素以外で実装するかarea要素のcoords属性をちゃんと指定してほしい
はてなブックマーク( http://b.hatena.ne.jp/ )のメニュー(トップ〜動画のあれ)はmap要素を用いて実装されています。この記事を書いた時点でのHTMLを引用します。
<div id="category"> <span> <img src="http://cdn-ak.b.st-hatena.com/images/scategory.png" usemap="#catmap" alt="カテゴリー" style="margin-top: -60px;"> </span> <map name="catmap" id="catmap"> <area coords="0,0,47,92" href="/" alt="トップ" title="トップ"> <area coords="0,0,87,92" href="/hotentry" alt="総合" title="総合"> <area coords="0,0,127,92" href="/hotentry?mode=general" alt="一般" title="一般"> <area coords="0,0,166,92" href="/hotentry/social" alt="社会" title="社会"> <area coords="0,0,232,92" href="/hotentry/economics" alt="政治・経済" title="政治・経済"> <area coords="0,0,297,92" href="/hotentry/life" alt="生活・人生" title="生活・人生"> <area coords="0,0,403,92" href="/hotentry/entertainment" alt="スポーツ・芸能・文化" title="スポーツ・芸能・文化"> <area coords="0,0,468,92" href="/hotentry/knowledge" alt="科学・学問" title="科学・学問"> <area coords="0,0,555,92" href="/hotentry/it" alt="コンピュータ" title="コンピュータ"> <area coords="0,0,632,92" href="/hotentry/game" alt="アニメ・ゲーム" title="アニメ・ゲーム"> <area coords="0,0,691,92" href="/hotentry/fun" alt="おもしろ" title="おもしろ"> <area coords="0,0,733,92" href="/video" alt="動画" title="動画"> </map> </div>
これはHTMLのイメージマップという機能を使用しています。img要素にusemap属性を指定すると、そのusemap属性に指定した値を持つmap要素に結び付けられます。そしてそのmap要素の子であるarea要素がimg要素のイメージのどの部分に対応するかは、area要素のcoords属性によって決まります。
area要素は、指定した順番から前面に並びます。上記の例の場合、トップが一番前面に来て動画が一番後ろ側になります。そして、area要素がhref属性を持っている場合、a要素と同じようにハイパーリンクとして扱われます。area要素にはshape属性を指定することもできますが、この属性を指定しない場合はrectangleというキーワードが指定されたものとして扱われます。
ここまでが前提知識。
Vimiumのhit-a-hintとの兼ね合い
Google Chromeの拡張にVimiumというものがあります。Vimiumを使うとウェブブラウジング中の全ての操作をキーボードのみで行うことができます。(デフォルトでは)fキーを押すと画面内のハイパーリンクの矩形内の左上あたりにヒントが浮かび上がり、その状態でヒントに表示されたキーを叩くと、そのリンク先に飛べるようになっています。これを「hit-a-hint」というらしいです。
この記事を書いている時点でのVimium(1.29)では、href属性付きのarea要素はハイパーリンクとして扱われません。つまりhit-a-hintに反応しません。僕個人としては、はてなブックマークはよく利用しているのでメニューもhit-a-hintを使って移動したい所です。実は既に対応させるパッチは書いているのですが、正直実用に耐えるレベルではありません。ちゃんとhref属性付きのarea要素をhit-a-hintに反応するように出来ているのに、です。
というのは、上記のHTMLのarea要素のcoords属性を見てもらうと分かるのですが、全て1番目と2番目が0に指定されています。この場合のcoords属性の4つの値に何を指定するかは以下の通りです。
rectangle 状態 では、area 要素は、正確に 4 つの整数を持たなければいけません。最初の整数は、3 つ目の整数より小さくなければいけません。そして、2 つ目の整数は、4 つ目の整数より小さくなければいけません。この 4 つの整数はそれぞれ、イメージの左端から矩形の左側までの距離、上端から上側までの距離、左端から右側までの距離、上端から下側までの距離を、すべて CSS ピクセルで表したものでなければいけません。
area 要素 - 組込コンテンツ - HTML要素 - HTML5 タグリファレンス - HTML5.JP
上記のはてなブックマークのメニューの場合、coords属性の1番目と2番目の値は0です。イメージの左端から矩形の左側までの距離とイメージの上端から上側までの距離は全てのarea要素で同じになります。
先程も述べましたが、hit-a-hintのヒントはハイパーリンクの矩形内の左上あたりに浮かび上がります。ここで、href属性付きのarea要素をハイパーリンクとして扱い、ヒントを表示させた場合にどうなるでしょうか。coords属性の値からも分かるように、全てのarea要素の左上の位置は同じなので、全てのヒントが重なってしまいます。ヒントが表示されるようにできたとはいえ、全部重なってしまっているのでは流石にユーザビリティ上問題ありです。というわけでまだ公開していません。
個人的にはこの実装は変だと思っていて(なんでcoords属性の1番目と2番目の値を0にしているのかよく分からない)、ちゃんとcoords属性をそれぞれの矩形の大きさに指定するか、それともnav要素なりなんなりを使ってa要素を使う普通のリンクとして実装するかしてほしいなあと思うわけです。
セキュリティ&プログラミングキャンプ「Rubyのバグを探せ」問題を解いてみた
セキュリティ&プログラミングキャンプ「Rubyのバグを探せ」問題 - 西尾泰和のはてなダイアリーを見て、面白そうだなーと思ったので挑戦してみた。
Evernoteにログを残しながらやってて、ダウンロードして解凍が完了したのが20時56分、makeが通ったのが23時49分なので、大体3時間かかった計算になる。Rubyのビルドすらやったことなかったし、難しくて途中で投げ出してしまうかもなーって思ったんだけど、ちゃんとmakeが通ったので良かった。
Evernoteのログは公開してもいいんだけど、ぐっちゃぐちゃなまま&解いた人で答えを公開しているっぽい人が見当たらない(自分が見つけられていないだけかもしれないけれど)ので今は公開していない。