2008年 07月 29日

gerry++

起きてすぐトイレ……しかも頭痛……

2008年 07月 25日

yukkuri

2008年 07月 20日

ゆの in Ruby エラーメッセージ

クソ長いです

#!/usr/bin/env ruby -Ku
# vim:set ft=ruby:
# ひだまりスケッチ× というファイル名で保存する必要があります
X = 365


















































































































































































































































































































































t = Time.now
t += 7 * 24 * 60 until t.wday == 4
n = t.strftime("X365次は%m月%d日25時25分からです><")
eval "class #{n} < Exception; end"



alias _ raise
$! = Kernel.const_get(n).new(File.read(__FILE__)[/< (.+!)$/, 1])













X / _ / X < 来週も見てくださいね!

出力はこんな風になります。

ひだまりスケッチ×:365: 来週も見てくださいね! (X365次は07月24日25時25分からです><)

方針としては

  • 365行目で raise させる

ってだけです。

Ruby のエラーメッセージはトップレベルの場合

filename:line: message (ErrroClassName)

になります。トップレベルではない場合は in`methodname` が入ってくるのでダメです。そこで _ を raise の alias にすることで、raise と書かなくても例外をゆのっち内で起こせるようにしました。_ には引数がないので、引数なしの raise となり、直前の例外が raise される効果になります。「直前の例外」は $! に入っており、代入することもできるので、例外を生成して直接 $! へ代入しています。

$! へ代入するクラスの名前が、エラーメッセージの括弧内に入るので、オマケで次週の TBS での放送日を入れることにしました。const_name として valid な名前にするのが結構めんどいうえに綺麗にならないですがこんなもんでしょうか。

短かいバージョン ファイル名も行数も関係なし。上のコードは _ でプログラムを抜けて「来週も見てくださいね!」が評価されないのですが、これだとされます。

#!/usr/bin/env ruby -Ku
# vim:set ft=ruby:

class X < (_ = Exception)
	class << self
		def /(o)
			self
		end

		def <(o)
			raise X, o.to_s
		rescue Exception
			$!.set_backtrace(["ひだまりスケッチ×365"])
			raise
		end
	end

end

class Object
	def method_missing(name, *args)
		name
	end
end

X / _ / X < 来週も見てくださいね!
ひだまりスケッチ×365: 来週も見てくださいね! (X)
2008年 07月 19日

gerry++

ガムくいすぎ?

Pure DOM なツリービルダー (べんり版 & 総合的には jQuery よりはやいこともあるよ版)

http://subtech.g.hatena.ne.jp/cho45/20071117/1195309573 の便利版

<div class="entry">
	<h2 class="title">#{title}</h2>
	<div class="body">
		#{body}
	</div>
	<div class="info">
		<span class="datetime">#{datetime}</span>
		<span class="author">#{author}</span>
	</div>
</div>

みたいな文字列が template1 に入ってて

var t = dom(template1, parent, {
	title    : "aaa<aaa>",
	body     : "foobar",
	datetime : "2008-07-19(0日前)T20 : 26 : 54+09 : 00",
	author   : "cho45"
});

ってやると #{foobar} がフィルされます。

ってだけだと別に普通にエスケープしながら置換したらいいじゃんって感じですが、返り値が便利です

t.root     //=> div.entry
t.title    //=> h2.title
t.body     //=> div.body
t.info     //=> div.info
t.datetime //=> span.datetime
t.author   //=> span.author

みたいにクラス名に対応する要素が入ってます (ルートは root に)。

ベンチマーク:

- "jQuery only $"        -> $(template1) しているだけ
- "jQuery pre-replaced"  -> #{} を置換してから $(template1)
- "jQuery"               -> $(template1) してから find/end を駆使してテキスト設定
- "dom()"                -> 上記関数使って一括設定

jQuery の find/end は (中身想像すればあたりまえですが) コスト高いです。でも jQuery 使っていて、先に HTML をばーーーって作ってしまってから、操作したい要素を取得したいケースは結構あって、find を使ってしまいがちです (というかそうしないと綺麗に書けない)

dom() だとパースして要素を追加するのと、欲しい要素の列挙を同時にやっているので、その分有利です。それと Pure DOM なのでテーブル関係のBKなハックを入れなくても parent を直接指定すれば問題ないです。

実体/数値参照を展開してないのでそのコード入れたらもっと遅いかもですね。

2008年 07月 17日

gerry++

海老名で途中下車、掃除中でまじあせる

2008年 07月 16日

はてなダイアリーキーワードの diff をみやすくする

キーワードの編集ページの履歴リンクをクリックすると、クリックした履歴の一つ前の履歴との比較を diff して表示します。

JavaScript での diff と format は http://ejohn.org/projects/javascript-diff-algorithm/ のをそのまんま使ってます。ちょー簡単にできた。

alias nopaste

.zshrc に追記した

if [ `uname` = "Darwin" ]; then
	alias nopaste='curl -F file=@- nopaste.com/a >&1 > >(pbcopy) > >(open `cat`) '
	alias nonopaste='pbpaste | nopaste'
else
	alias nopaste='curl -F file=@- nopaste.com/a'
fi

foobar | nopaste とかやると、ブラウザで結果を開きつつ、クリップボードに URL がコピーされて、すぐどっかに貼れるようになる。

2008年 07月 14日

CMS

なんか washer-in-the-rye.com を管理するにあたって簡単な CMS が欲しいので要件を整理しておく (theruck でつくる)

  • 簡単に編集できて管理できること
  • マルチリンガルであること
  • ERB をテンプレートに
  • HTML 直編集したい (あのページは実は microformats と RDF 埋め込みによる XSLT での RDF への変換をサポートしています)

思いついたこと

  • git 使いたい
    • git push すると本番に反映されるように
  • 別に本番環境で確認できる必要なくね?
    • ruby foobar.rb するとローカルウェブサーバが立ち上がって確認できればいい

ゆの まとめ用スクリプト

ブクマからキーワードページのテーブルにするやつ

require "rubygems"
require "mechanize"
require "active_support"
require "time"

@ua = WWW::Mechanize.new

puts "|*言語|*リンク|"
begin
	results = []

	uri = "http://b.hatena.ne.jp/cho45/atomfeed?tag=%E3%82%86%E3%81%AE%20in%20language"
	loop do
		begin
			warn uri
			@ua.get uri
			doc = XmlSimple.xml_in(@ua.page.body)
			raise "Bug?" unless doc["entry"]

			results.concat doc["entry"]

			next_link = doc["link"].find {|link| link["rel"] == "next" }
			break unless next_link
			uri = next_link["href"]
		rescue RuntimeError
			sleep 1
			retry
		end
	end

	results.map! {|entry|
		entry.update("lang" => entry["subject"] - ["ゆの", "language", "ゆの in language", "ひだまりスケッチ"])
	}

	results = results.sort_by {|entry| [entry["lang"], entry["issued"]] }.map { |entry|
		warn entry["subject"].inspect
		"|%s|[%s:title]|" % [
			entry["lang"],
			entry["link"].find {|link| link["rel"] == "related" }["href"],
		]
	}

	raise "Bug?" if results.uniq!
rescue RuntimeError
	sleep 1
	retry
end
puts results

なんかちゃんとフィードがとれないことがあるのでチェックかけてリトライしてる。