2010-01-02
■ [RUBY][TDD]RSpec、describe のネスト 
- Rspecでdescribeをネストしたときの動作 - craftoneの日記
- before と after が実行される順番について
- http://wiki.paulownia.jp/rspec
2010-01-01
2009-12-31
2009-12-29
■ [RUBY]はてなダイアリー AtomPub API 
これ見ながら Ruby で試しに日記を書き込もうとしているんだけどうまくいかない、401 エラーが返ってくる。認証に失敗してるっぽいんだけど、何が悪いのかいまいちよく分からない。
上記ページに載ってる Ruby 用のサンプルコードだとうまく動かなくて、get_service とかやってるところを代わりに手動で collection_uri を作るようにしたらうまく動いた。
require 'rubygems' require 'atomutil' username = 'はてなID' password = 'hatena_password' auth = Atompub::Auth::Wsse.new :username => username, :password => password client = Atompub::Client.new :auth => auth collection_uri = 'http://d.hatena.ne.jp/%s/atom/blog' % username entry = Atom::Entry.new( :title => 'My Entry Title', :updated => Time.now ) entry.content = <<EOF エントリー本文だよ EOF puts client.create_entry collection_uri, entry
下書き投稿とかする場合には HatenaClient クラスを定義する必要があるっぽいけど、今のところ自分は必要としていないので試していない。
あと削除も atomutil - RubyでAtomPubを操作するパッケージをリリースしました - Codin’ In The Free World を見ながらやったらできた。
追記:今試してみたら、はてなダイアリーAtomPubとはに載ってる get_service を使ってるサンプルでも動いた。よく分からない。
2009-12-28
■ [CODE READING][TEST]testing test 
cucumber の spec 面白そう、一通り目を通す。
2009-12-27
■ 使い方覚えたいもの 
- git
- gearman
- google app engine
■ [FOS]Mac の mecab-ruby ライブラリで文字化け (?) する 
なんかよく分からないんだけど、/opt/local/etc/mecabrc を読めていないらしく、左記のファイルに指定した辞書を読みに行っていないっぽい。
require 'MeCab' m = MeCab::Tagger.new n = m.parseToNode(STDIN.read) while n puts n.surface n = n.next end
~# ruby test.rb
動く犬
^D
###
#########
#
/opt/local/etc/mecabrc を $HOME/.mecabrc にコピーしたらうまく動いた。
~# ruby test.rb 動く犬 ^D 動く 犬
■ [PROGRAMMING]プログラム 設計 メモ 
全然基礎がなっていないので何かを作ろうとするときにいつもどういう設計にすればいいか分からなくて困るんだけれど、そうしている中でも最近作りながら考えたり意識していること。
- 手続き型で作るかオブジェクト指向で作るか
- クラス設計をどうするか
- クラス名が「名詞」になるように作る
- 「魔法」っぽく見えるように作る
- 内側の低レベルな汚い処理は奥のほうに隠しておいて、インタフェースではもっとレベルが高い問題を扱うようにする
- 抽象度を合わせる
- 「魔法っぽく〜」とも関連すると思うんだけど、顧客操作なのにいきなり SQLStatement クラスが出てきたりとかカッコわるい
- 抽象度を合わせるためなら、一行メソッドを定義してもよい (プロダクティブ・プログラマ)
- 組み込みクラスを拡張するように作る
- Array Hash String とか (特に Hash) で済ませてしまいがちのところを、もっとそのデータに独自の振る舞いを持ってほしくないか考える
- デザインパターンを採用する
- 条件文や繰り返し文を減らす
2009-11-24
2009-06-29
2009-06-13
■ [RAILS]Rails っぽくないデータベースを ActiveRecord で扱う 
- テーブル名
- 命名規則に従っていないテーブル名を指定する
- ActiveRecord::Base#set_table_name
- 命名規則に従っていないテーブル名を指定する
- リレーション
- 命名規則に従っていない名前のプライマリキーを指定する
- ActiveRecord::Base#set_primary_key
- 複合プライマリキーを指定する
- 命名規則に従っていない名前のプライマリキーを指定する
- データベース
- 複数のデータベースに接続する
- database.yml に development みたいな環境を使いたいデータベース分作成して、ActiveRecord::Base#establish_connection で指定する - Ruby on Railsで複数のデータベースを使用する方法 (山本隆の開発日誌)
- Magic Multi-Connections をつかって、ひとつの Rails アプリから複数のデータベースを利用する - KazusaAPI開発日誌 - KDRIグループ
- Ruby/ActiveRecordで動的に接続先を変更する - 俺の基地
- UNION したい
- だいたいメソッドを使わずに find_sql で SQL 文を直接指定しろっていう風潮 - ActiveRecord model that uses two tables (kind of like UNION - Ruby Forum
- 同じテーブルで走らせた SELECT の結果を UNION する ActiveRecord::Base#union の実装 - Sliced Software - A Simple .union Extension For ActiveRecord
- 複数のデータベースに接続する
- 関連
- HowToUserLegacySchemas - Configure environment.rb to not look for pluralized table names => Rails Wiki
2009-06-09
■ なじまないものメモ 
- Emacs / screen の画面分割
- screen のスクロールバックモード
- 自分の場合ターミナルでコピーするときって、だいたい Windows とか Mac のクリップボードに入れたい場合がほとんどなんだけど、screen のスクロールバックはターミナルソフトのスクロールバーでさかのぼれないし、コピーしてもクリップボードに入らないから、使い勝手が良くない
- screen 起動しているときはターミナルのスクロールバーが効かないから、hardcopy -h tmp.txt とかして、いったんデタッチして cat tmp.txt してターミナルのスクロールバーでさかのぼって、選択してコピーするとかになっちゃう
- あきらかに効率わるい、どうにかしたい
- Mac で pbcopy と連携するやつは使いやすそう、あとで試してみる
2009-05-26
■ yum.conf に書く base とか update とかの URL 
ftp://ftp.riken.jp/pub/Linux/fedoralegacy/fedora/3/os/i386/repodata/repomd.xml
を読み込もうとしているので、
ftp://ftp.riken.jp/pub/Linux/fedoralegacy/fedora/3/os/i386/
の部分までを書く。
[base] name=Fedora Core $releasever base baseurl=ftp://ftp.riken.jp/pub/Linux/fedoralegacy/fedora/$releasever/os/$basearch/
2009-05-04
■ [RUBY] 
- ||=で変数初期化をする。 - t-imaizumiのMacとかのはなし
- ARGVはfrozen,代入してもfrozen.dupで複製
- OptionParser - Rubyリファレンスマニュアル
- Ruby の三項演算子は改行使えない
- mechanize、相対 URL を get に指定すると自動的に計算して絶対 URL を返してくれる
2009-05-01
■ [WINDOWS] 
- hosts ファイルの場所
- Windows XPの場合 → C:\WINDOWS\system32\drivers\etc
2009-04-29
2009-04-27
2009-04-20
■ [RUBY] 
- Class: Nokogiri::XML::Node
- CGI.escapeHTML / CGI.unescapeHTML
2009-04-12
■ [RAILS]1.2.6 (MacOS X) から 2.2.2 (WIndows XP) へのアップグレード 
- rails を 1.2.6 から 2.2.2 にアップグレードした際のエラー回避、environment.rb に以下を追加する(2008-01-04 - なんとなく日記)
config.action_controller.session = {
:session_key => '_railsapp_session',
:secret => 'thegreatmanagerknowseverythingsoftheproject'
}
- 既存の Rails アプリを 2.2.2 にアップグレードするには、version が 2.2.2 の rails コマンドで rails /path/to/rails_app_dir すればよい
- 既存のファイルを新しいファイルに置き換えるかどうか尋ねられるので答えていく
- sqlite3-ruby を Windows XP にインストールできない
- gem install --version 1.2.3 sqlite3-ruby でいける(とりあえず - toganoの日記)
- paginate が標準ではなくなっている
- will_paginate というのがあるらしいけど、やっぱ自前で作ったほうがいいか
- will_paginateのインストール方法が変わっていた - idesaku blog
2009-04-11
■ [RAILS] 
- app/view/layouts/コントローラ名.rhtml がない場合のみ app/view/layouts/application.rhtml が使われる
- ヽ( ・∀・)ノくまくまー(2005-07-21)
- acts_as_searchable - 全文検索
- バッチ処理的なことをrailsでやりたいとき - くりまるwebつくる
- ActiveRecord と ActiveSupport を使ってコマンドラインアプリを作る - ma2の日記 - ActiveRecord と database.xml を手動で読み込む方法が書いてある
- ちょっと複雑なことやろうとすると xmpp4r-simple じゃだめっぽい
- find_or_create_by_{カラム名} 便利
2009-03-31
■ 
CREATE TABLE SERVERS ( id INTEGER PRIMARY KEY, name STRING, ip STRING, owner_id INTEGER ); CREATE TABLE ROUTINGS ( id INTEGER, from INTEGER, to INTEGER, port INTEGER, description TEXT, map_id INTEGER, owner_id INTEGER ); CREATE TABLE MAPS ( id INTEGER, title TEXT, description TEXT ); CREATE TABLE USERS ( id INTEGER, name STRING, password STRING ); CREATE TABLE PORTS ( id INTEGER, port INTEGER, description TEXT );
2009-03-28
■ [DATABASE]MySQL レプリケーション障害の回復 
- [MySQLウォッチ]第18回 レプリケーションのトラブル脱出:ITpro
- Slave_SQL_Running が NO になった場合の対処、基本的には以下の手順
- SHOW SLAVE STATUS \G; でどの SQL 文でレプリケーションが止まったのか特定
- マスター DB サーバ側でレプリケーションが止まったデータベースを丸ごとバックアップ
- バックアップした .sql ファイルをスレーブ側に持っていって復元
- マスター DB サーバ側で SHOW MASTER STATUS; でログの名前と位置をメモ
- スレーブ DB サーバ側でログの名前と位置を指定して再起動
- STOP SLAVE;
- CHANGE MASTER TO 文でログの名前と位置を再設定
- START SLAVE;
- スレーブ DB 側で SHOW SLAVE STATUS; を実行し、Slave_SQL_Running が Yes になっていることを確認する
- この方法の問題点は、マスタでバックアップした sql ファイルをスレーブに転送するのに時間がかかってしまうことかな
2009-03-15
■ [UNIX]Debian、USB のマウント 
- USBメモリをマウントせよ。Debian - 長靴をはいたネコ
- これを見ながらやったらできた。
- mount -t vfat /dev/sdb1 /mnt/usbmem でできた。
2009-03-07
■ [MOBILE] 
- docomo 端末では XHTML でなければスタイルシートを使えない
- docomo 端末では style が使えるのはタグの属性としてのみ。ただし a タグの疑似クラス(a:hover とか)のみはインラインの style タグに指定できる
- docomo 端末で XHTML を表示させるためには、HTTP レスポンスヘッダの Content-Type と、HTML ヘッダの Content-Type の両方に "application/xhtml+xml" を指定する必要がある
- Apache で application/xhtml+xml を HTTP レスポンスヘッダに指定するには、.htaccess の AddType でやるか拡張子を .xhtml にすればよい
- SoftBank 端末ではリダイレクトに制限がある。C 型は 2 回まで、それ以外は 3 回まで
- AU の端末は textarea に 1024 文字までしか入力できない
2009-02-18
■ [JAVASCRIPT]階層、回想、実装 ![[JAVASCRIPT]階層、回想、実装 - 何か作りながら書くメモ (tily) を含むブックマーク [JAVASCRIPT]階層、回想、実装 - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
階層を深くする場合(1)
BEFORE
<ul> <li>パン</li> <li>米</li> <li>カレーライス</li> <!-- この要素の階層を深くする --> <li>パスタ</li> </ul>
AFTER
<ul> <li>パン</li> <li>米 <ul> <li>カレーライス</li> </ul> </li> <li>パスタ</li> </ul> <!-- 現在の <li>カレーライス</li> を削除 --> <!-- 新しく li 要素を 1 つのみ持つ ul 要素を作って直前の li 要素に挿入 -->
階層を深くする場合(2)
BEFORE
<ul> <li>パン</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> </ul> </li> <li>リゾット</li> <li>パスタ</li> </ul>
AFTER
<ul> <li>パン</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
階層を深くする場合(自分より深い階層を持っている場合)
BEFORE
<ul> <li>パン</li> <li>米 <ul> <li>カレーライス</li> <li>グリーンカレー <!-- 階層を深くしたい --> <ul> <li>レッドカレー</li> <li>キーマカレー</li> <li>カツカレー</li> </ul> </li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
AFTER
<ul> <li>パン</li> <li>米 <ul> <li>カレーライス <ul> <li>グリーンカレー</li> <li>レッドカレー</li> <li>キーマカレー</li> <li>カツカレー</li> </ul> </li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
階層を深くできない場合
<ul> <li>パン</li><!-- リストの 1 番目の要素の場合 --> <li>米 <ul> <li>カレーライス</li><!-- リストの 1 番目の要素の場合 --> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
階層を浅くする場合(要素の一番前)
BEFORE
<ul> <li>パン</li> <li>米 <ul> <li>タロイモ</li><!-- 浅くしたい --> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
AFTER
<ul> <li>パン</li> <li>タロイモ</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> </li> <li>パスタ</li> </ul>
階層を浅くする場合(要素の中間)
BEFORE
<ul> <li>パン</li> <li>タロイモ</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> <li>パスタ</li><!-- 階層を浅くしたい --> <li>ナポリタン</li> <li>カルボナーラ</li> </ul> </li> </ul>
AFTER
<ul> <li>パン</li> <li>タロイモ</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> </ul> <li>パスタ <ul> <li>ナポリタン</li> <li>カルボナーラ</li> </ul> </li> </ul>
階層を浅くする場合(要素の末尾)
BEFORE
<ul> <li>パン</li> <li>タロイモ</li> <li>米 <ul> <li>カレーライス</li> <li>牛丼</li> <li>雑炊</li> <li>リゾット</li> <li>パスタ</li><!-- 階層を浅くしたい --> </ul> </li> <li>お好み焼き</li> </ul>
先頭・中間・末尾での場合分けの他に、子要素を持っているかどうかで場合分けする必要がある
- 深くする
- 先頭/末尾
- 親要素の最初の子である場合、
- 親要素の最後の子である場合、
- 子要素の有無
- 子要素がある場合、
- 子要素がない場合、
- 無効な場合
- 先頭/末尾
- 浅くする
- 先頭/中間/末尾
- 親要素の最初の子である場合、
- 親要素の中で previousSibling と nextSibling がいる場合、
- 親要素の最後の子である場合、
- 子要素の有無
- 子要素がある場合、
- 子要素がない場合、
- 無効な場合
- 先頭/中間/末尾
2009-02-14
■ [JAVASCRIPT] 
<ul> <li>パン</li> <li>ごはん</li> <li>パスタ</li> </ul>
- Enter キーイベントをキャッチして、なんか処理をラップする必要がある
2009-02-11
■ OpenOffice + Mac、日本語がファイル名に入ったファイルを読み込もうとするとクラッシュする 
■ [JAVASCRIPT]Arguments.callee とか 
- オブジェクト指向覚えたい
- GUI に対してうまくオブジェクト指向を適用できるようになりたい
- FastLadder を参考にする
2009-02-08
■ [JAVASCRIPT] 
- createTextNode
- Element#tagName
- NodeType
- こりゃオブジェクト指向覚えないと全然きれいなコード書けそうにないな。あと DOM API をもっと覚えたい(Firebug の DOM タブをよく見るようにする)
- Script雑感: Javascript:DOMオブジェクトかECMAオブジェクトかを判定する。
- クロスブラウザでElement / Nodeを判定 - DenkiYagi
- 2番目以降の要素じゃないと >> できないようにしたい
2009-02-07
■ [JAVASCRIPT]リッチテキストエディタの実装を調べる 
- TinyMCE
- KeyTypeListener.js
- display:none の div で囲まれた textarea タグ + iframe で実現してるっぽい
- というか designMode というのがあるらしい
- 画像をドラッグ & ドロップできないようにしたい
アウトライナ独自のキーバインドの実装
- タブキーでフォーカスが次の要素に移らないようにする
- Tab で階層を深くする
- Shift + Tab で階層を浅くする
- Delete キーと BackSpace が押されたタイミングで現在のカーソルの位置を取得して、リストタグが消されないように制御する
- 範囲を指定して削除
- 選択範囲が行をまたがった場合に、リストアイテム単位で選択されるようにする
- 右クリックメニューからカット/コピー/ペースト/削除が選択された場合の制御
- 制御できるのかな
- リンク機能
- URL (http://www.example.com) が張られたら自動的に <a href="http://www.example.com/">[その URL のタイトル]</a> に変換する
- WikiName というかページ名を自動的に判別してリンクにする
- Emacs / Shell の C-k と C-y (kill-line と yank-line) を実装したい
- ビジュアル単位じゃなくて、アイテム単位でカット & ペースト
- 結局、サーバーサイドで正しい階層になっているかを判定するような機構がないとばんばん XML valid じゃない文字列が保存できてしまいそう
- MarkDown とか PukiWiki 記法のリストで出力できる機能
- OPML で出力できる機能
- テキストが削除されたときに発生するイベント
- = onChange イベント時に差分をとって、文字数が減っていた場合?
- 高度な機能としては、リストのサブアイテムを開閉する機能
- DOM で childNodes を指定して display:none にするみたいなのでいけるかも(?)
- MultipleSelection よさそう
- execCommand : indent, outdent, insertHTML
- Javascript Outliner
2009-02-05
■ [JAVASCRIPT]LDR で記事に含まれる画像だけ表示する GreaseMonkey スクリプト 
// ==UserScript== // @name LDR Only Images // @namespace http://d.hatena.ne.jp/linwttaa // @include http://reader.livedoor.com/reader/ // ==/UserScript== (function(){ var w = unsafeWindow; w.register_hook("before_printfeed", function(feed) { feed.items.forEach(function(item) { urls = item.body.match(/"https?:\/\/.+?(jpg|png|gif)"/g); if(urls == null) { return; } item.body = ''; for(i=0;i<urls.length;i++){ item.body = item.body + '<img src=' + urls[i] + ' /><br />'; } }); }); })();
■ [EMACS]shell-mode で履歴を移動する 
- M-n, M-p
- らしいんだけど Carbon Emacs では動かない(?)
- 他にもいろいろあるみたい
2009-02-04
■ [RUBY]フィード用 OPML を作るサンプルコード 
require 'rexml/document' xml = REXML::Document.new xml << REXML::XMLDecl.new('1.0', 'UTF-8') opml = xml.add_element('opml', {'version' => '1.0'}) head = opml.add_element('head') body = opml.add_element('body') outlines = body.add_element('outline', {'text' => 'Subscriptions'}) 1.upto 10 do |i| outlines.add_element('outline', { 'title' => i, 'htmlUrl' => i, 'text' => i, 'type' => 'rss', 'xmlUrl' => i, }) end xml.write STDOUT
出力
<?xml version='1.0' encoding='UTF-8'?><opml version='1.0'><head/><body><outline text='Subscriptions'><outline title='1' text='1' xmlUrl='1' type='rss' htmlUrl='1'/><outline title='2' text='2' xmlUrl='2' type='rss' htmlUrl='2'/><outline title='3' text='3' xmlUrl='3' type='rss' htmlUrl='3'/><outline title='4' text='4' xmlUrl='4' type='rss' htmlUrl='4'/><outline title='5' text='5' xmlUrl='5' type='rss' htmlUrl='5'/><outline title='6' text='6' xmlUrl='6' type='rss' htmlUrl='6'/><outline title='7' text='7' xmlUrl='7' type='rss' htmlUrl='7'/><outline title='8' text='8' xmlUrl='8' type='rss' htmlUrl='8'/><outline title='9' text='9' xmlUrl='9' type='rss' htmlUrl='9'/><outline title='10' text='10' xmlUrl='10' type='rss' htmlUrl='10'/></outline></body></opml>
■ [RUBY]Twitter で自分が follow してるユーザーの RSS を OPML で取得 
- 昨日の続き
- Nokogiri::XML::Element の小要素群の中から XPath で検索しようとしてるんだけど、どうも document 全体から検索されてしまう
- p 'abbbxabx'.gsub(/a(b+)/, '\1') #=> "bbbxbx"
- RDocul.us: nokogiri rdoc documentation
- CSS セレクタに関するおさらい | WWW WATCH
- RubyでXML操作: Netsphere Laboratories
- REXML は Ruby には標準でついてくる
- とりあえずできた
require 'rubygems' require 'mechanize' require 'Logger' require 'rexml/document' username = ARGV[0] password = ARGV[1] log = Logger.new(STDOUT) log.info("logging in") agent = WWW::Mechanize.new agent.get('http://twitter.com/') agent.page.form_with(:action => 'https://twitter.com/sessions') {|f| f.field_with(:name => 'session[username_or_email]').value = username f.field_with(:name => 'session[password]').value = password f.click_button } users = [] page = 1 while 1 log.info("processing page #{page}") agent.get("http://twitter.com/friends?page=#{page}") break if agent.page.search('table.doing tr').empty? agent.page.search('table.doing tr').each {|user| next if(not user.search('img.lock').empty?) users.push( :name => user.search('td strong a').text, :twitter_id => user.get_attribute('id').sub(/person_(\d+)/, '\\1') ) } page = page + 1 end xml = REXML::Document.new xml << REXML::XMLDecl.new('1.0', 'UTF-8') opml = xml.add_element('opml', {'version' => '1.0'}) head = opml.add_element('head') body = opml.add_element('body') outlines = body.add_element('outline', {'text' => 'Subscriptions'}) users.each do |user| outlines.add_element('outline', { 'title' => "Twitter / #{user[:name]}", 'htmlUrl' => "http://twitter.com/#{user[:name]}", 'text' => "Twitter / #{user[:name]}", 'type' => 'rss', 'xmlUrl' => "http://twitter.com/statuses/user_timeline/#{user[:twitter_id]}.rss", }) end xml.write STDOUT
2009-02-03
■ [RUBY]Twitter で自分が follow してるユーザーの RSS を OPML で取得 
- WWW::Mechanize の search メソッドって Hpricot じゃなくて Nokogiri を使っているんだ
- Nokogiri では search で返ってきた値に対して empty? メソッドを使って空かどうかを判定できる
- なんか agent.page.search('//table[@class="doing"]/tbody').empty? がページ数が増え続けても true にならないな、と思っていたら tbody は Firebug が付加したやつだった。直で HTML のソース読むようにしなきゃだめだな
- とりあえず id を取得するところまで書いた。あと少し
username = ARGV[0] password = ARGV[1] ids = [] log = Logger.new(STDOUT) log.info("logging in") agent = WWW::Mechanize.new agent.get('http://twitter.com/') agent.page.form_with(:action => 'https://twitter.com/sessions') {|f| f.field_with(:name => 'session[username_or_email]').value = username f.field_with(:name => 'session[password]').value = password f.click_button } page = 1 while 1 log.info("processing page #{page}") agent.get("http://twitter.com/#{username}/friends?page=#{page}") break if agent.page.search('//table[@class="doing"]/tr').empty? agent.page.links.each {|l| if(l.href.match('/direct_messages/create/(\d+)')) ids.push($1) end } page = page + 1 end ids.each do |id| p id end
■ get_twitter_id_by_name.rb 
require 'rubygems' require 'mechanize' agent = WWW::Mechanize.new agent.get "http://twitter.com/#{ARGV[0]}" agent.page.links.each do |l| if l.href.match('/statuses/user_timeline/(\d+?).rss') puts $1 end end
2009-02-02
■ fragments 
- Bliki 読みたい
- Rails のソースを読む、あるいは ruby script/* を使いまくる
- Active::Record::SchemaStatements
- ruby script/generate migraiton InitialSchema # -> db/migrate/001_initial_scheme.rb
- 削除するコマンドは無いのか
- svn propedit svn:mime-type file.txt
- svn propdel svn:mime-type file.txt
- svn の属性についてもっと知る
- rake db_schema_dump # SQL ファイルから AR のスキーマファイルを生成
- svn info, svn merge, svn lock, svn resolved について知る
- プロパティシートの実装してみたい
- ある RSS が本当にその人が配信しているフィードかどうか問題 ← プロフィールサービスとか
- marquee って Firefox でも使えるんだ
- migration ファイルの書き方覚えたい
- Windows で gem をアップデート
- DDL DML
- PHP Smarty debug_print_var
- "Magic is not inherently a bad word" (Rails Philosophy)
- 自分がウェブの辞書で調べた単語を DB に保存しておきたい
- mbstat
- BLOB (Binary Large OBject)
- ハッシュによる独自性判定は論理積の処理を減らす
- HTTP 1.0 と 1.1 の違い
- Twitter 自分の発言をキャッシュして全文検索
- WWW::Mechanize と Hpricot
- 天気を XMPP アカウントのステータスに投稿する Ruby プログラム
- OpenFastladder の BASIC 認証対応
- OpenFastladder でフィードのタイトルを変更できるようにする
- ホットスタンバイ/コールドスタンバイ
- VIM C-w + で画面を広げる
- PHP Symphony
- vim ものぐさなマッチの正規表現が Perl 系と違う。 \{-1,} みたいなやつ
- 上級者向けとかライトユーザ向けとかじゃなくて、自分と同じ美的感覚を持つ人に自分の作ったサービスを使ってもらいたい
- URL を自動的に補完してくれる、 Wedata とマッシュアップしたアプリ
- 翻訳メモリを作りたい
- HTML の仕組み + JavaScript で何か作れないかなぁ
- Plagger + WWW::Mechanize
- Hpricot の由来
- ri String.gsub
- RFC の読み方を学びたい (should とか must とか)
- /etc/init.d/iptables
- Hpricot::Doc#search ← XPath あるいは CSS のセレクタが使える
- るびまの記事を過去から遡って試す
- HTML head meta タグの http-equiv ってまさに HTTP メッセージヘッダのフィールドと等価って意味なのか
- MVC の論文訳したい
- WWW::Mechanize と HTML_QuickForm ってアプローチが似てる
- Win と Mac で emobile 環境の共有、試す
- ログイン時にそのサーバーのいろいろの情報を表示するシェルスクリプト書きたい
- fortune みたいに使いたい
- クローラー作ってみたい ← Cron とか Web アプリ以外の要素
- mkdir -p # 存在しない親ディレクトリも作る
- Apache バーチャルホストの設定
- DMZ (De-millitarized Zone)
- NFS /etc/export
- /etc/fstab
- setuid
- pushd, autopushd
- 無名関数
- LIST と SEARCH RESULT って結局しぼられているかそうでないかの違いしかないんだな
- zsh の bindkey -e (Emacs っぽいショートカット)
- svn log -r PREV
2009-01-31
■ [ABOUT]この日記のスタイルシート 
ベース:nimbus
ヘッダ
<div class="main"> <hatena name="sectioncategory" template="hatena-module">
フッタ
(なし)
スタイルシート
.main .calendar { margin:0 0 0 10px; } .main .day { margin:0 0 3em 0; } .hatena-sectioncategory li{ float: left; display: inline; margin: 0px; border-right: 1px solid #303030; padding-left: 5px; padding-top: 0px; padding-right: 5px; padding-bottom: 0px; } h1{ padding: 30px 10%; background-color: #303030; border-bottom: 0; background: #303030 url(20061206213959.gif) repeat-x scroll left 75px } .hatena-modulebody { background: none; background-color: #303030; } ul.hatena-sectioncategory { height: 3.0em; } .hatena-moduletitle { display: none; border-bottom: 0px; } #simple-header { background-color: #303030; color: #303030; } #logo-hatena, #logo-diary { display: none; } #simple-header ul li a { color:#303030; text-decoration:none; } #simple-header ul li a:hover { color:#F0F0F0; text-decoration:none; } input[name='submit'] { display: none; } #simple-header input.search-button { color: #0485CD; }
■ プロジェクトのスケーラビリティについて 
- ウェブアプリケーションを構築したり、Wiki を導入したりするより、共有フォルダ + エクセルですませたほうがいいこともある
- というよりそういうことのほうがほとんどなんじゃないかな。特に IT 業界以外の場合(ウェブアプリ構築には多大なスキル習得のコストが必要になるし、Wiki もそこまでじゃないけど記法や使い方の習得にコストがかかる)
- だから当然、軽い感じのプロジェクトは軽い感じの身近なツールですませるべきなんだけど、そこからプロジェクトが大規模になったときに、Excel だとバージョン管理がめんどくさかったり、必要な機能がそろってない、みたいなことになるだろう
- そういうときに、ウェブアプリケーション構築や Wiki に乗り換えるための、移行作業にもコストがかかるわけで、そういうのも見越してプロジェクトにどんなコミュニケーションツールを使うか考えるべきだろう
■ [RAILS] 
- ActiveRecord::Base
- ActiveRecord::Migration
2009-01-30
■ [RAILS][RUBY]pylori*style wiki - RailsでWikiクローンを作る ![[http://tam.qmix.org/wiki/Minki00.html:title=pylori*style wiki - RailsでWikiクローンを作る] - 何か作りながら書くメモ (tily) を含むブックマーク [http://tam.qmix.org/wiki/Minki00.html:title=pylori*style wiki - RailsでWikiクローンを作る] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- Rails Magic、updated_at という名前で datetime 型のカラムには自動的に更新日時が入る
- やっぱりクラスメソッドは SomeClass.some_class_method、インスタンスメソッドは SomeClass#some_instance_method って表記するみたいだな
- ruby script/generate Controller Wiki new show edit list
- メイン画面の Wiki コントローラー(作成・編集・表示等)と、管理者画面用の Admin コントローラー
- start_form_tag, end_form_tag
- layout - hoge コントローラー用レイアウトファイルの置き場所は /app/views/layouts/hoge.rhtml
- 対応するビューを持たないアクションは、どこかに redirect_to するっていう感じか
- ActiveRecord#update_attributes - 入力フォームの値に基いてテーブルの行を更新するのによく使われる
- LoadingModule - ヽ( ・∀・)ノくまくまー(2005-08-10)
- require と load の違い (組み込み関数 - Rubyリファレンスマニュアル)
- require は一回だけ読み込む、load は無条件に読み込む
- require は .rb を自動補完する、load はしない
- プライベートなインスタンス変数は、クラスフィールドに宣言するんじゃなくて initialize の中で宣言&初期化してしまっていいんだな (Hiki からコピーした formatter_default.rb)
- routes.rb について - ヽ( ・∀・)ノくまくまー(2005-07-25)
- コントローラークラスのフィールドの中での layout 'レイアウト名'
- request.post?
- Ruby のシングルクオートとダブルクオートの使い分けって、変数展開以外に何かあるのかな
- 個別のテンプレートファイルから layout 用のテンプレートファイルに値を渡してやってる?
- MVC 間での値の受け渡し方みたいのをまとめる必要がある
- コントローラーで値を設定した conf がビューから読めなかったので、@conf に置換したらうまく動いた。でも、インスタンス変数ってインスタンスで共有されているわけで、気持ちわるいか
- LoginEngine pylori*style wiki - LoginEngineを使ってみる
- String#crypt
- app/models/User.rb のソース、self って何だろう
- 認証のところで CSRF 出てきた
- flash は次のアクションに限って伝達される、session はブラウザを開いている間ずっと伝達される
- フィルター、before_filter とか
- 本番環境で動かす
- 書いてある通り Apache + FastCGI にチャレンジ
- ただし Apache は 1.3 じゃなくて 2.2.9
- sudo port install mod_fastcgi
- sudo gem install fcgi
- httpd.conf に LoadModule, AddHandler の設定と、VirtualHost(minki.localhost) の設定、IfModule で FastCGI 用のディレクトリの設定(参考:localhostでバーチャルホストを切る - toytools log)
- /etc/hosts で minki.localhost を 127.0.0.1 に割り当てる
- パーミッションのエラーでこける ← 今ここ
2009-01-29
■ [RUBY]Rubyist Magazine - RubyOnRails を使ってみる 【第 3 回】 ActiveRecord ![[http://jp.rubyist.net/magazine/?0006-RubyOnRails:title=Rubyist Magazine - RubyOnRails を使ってみる 【第 3 回】 ActiveRecord] - 何か作りながら書くメモ (tily) を含むブックマーク [http://jp.rubyist.net/magazine/?0006-RubyOnRails:title=Rubyist Magazine - RubyOnRails を使ってみる 【第 3 回】 ActiveRecord] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :dbfile => 'test.db')
- class User < ActiveRecord::Base end
- user = User.new; user.name = 'John'; user.occupation = 'Musician'
- user.save
- User.find(:all)
- Class#methods
- ActiveRecord, find_all とか find_first とかなくなって、ActiveRecord#all とか ActiveRecord#first とかになったのか
- find のプレースホルダー、? の代わりに名前付きのパラメータを渡すこともできる
- ActiveRecord、MacBook だと /usr/lib/ruby/user-gems/1.8/gems/ にあった
- よくわからない -「self.append_features(base) は include 時に呼ばれるのでしたね。そして module ClassMethods は base.extend されているので、ここで定義されたメソッドは base (= ActiveRecord::Base) のクラスメソッドとして扱われます。ライブラリを分割する手法として非常に参考になります。」
- Rails の config/database.yml は establish_connection メソッドに渡すためのデータを定義してたんだ
- establish_connection で確立した DB 接続は、以降 ActiveRecord::Base.connection で参照できる
- Test::Unit
- テーブルが複数形で、それに対応するクラスが単数形
- :has_many とか :belongs_to とか試す
- 後半はとりあえずざっと目を通す感じで読んだ
■ [RUBY][DATABASE]sqlite3とActiveRecordを単体で使うテスト - urekatのスカンク日記3 ![[http://d.hatena.ne.jp/urekat/20080923/1222169086:title=sqlite3とActiveRecordを単体で使うテスト - urekatのスカンク日記3] - 何か作りながら書くメモ (tily) を含むブックマーク [http://d.hatena.ne.jp/urekat/20080923/1222169086:title=sqlite3とActiveRecordを単体で使うテスト - urekatのスカンク日記3] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- $stderr
- Time.now
2009-01-28
2009-01-24
■ [RUBY]BookBoard に登録している ASIN のリストを取得して MediaMarker に登録する Ruby プログラム 
- RubyのWWW::Mechanizeを解説 for 0.9 (仮) - きたももんががきたん。
- コマンドラインからのパスワード入力機能をつける - にたまごほうれん草
- logger - Rubyリファレンスマニュアル
bb2mm.rb
#!/usr/local/bin/ruby require 'Bookboard.rb' require 'MediaMarker.rb' # get Bookboard username/password print 'input your Bookboard username:' uname = $stdin.gets.chop print 'password:' system 'stty -echo' pass = $stdin.gets.chop system 'stty echo' print "\n" asin_list = Array.new bb = Bookboard.new(uname, pass) bb.login 0.upto(3) do |num| asin_list.concat bb.asin_list_by_cat(num) end # get MediaMarker username/password print 'input your MediaMarker username:' uname = $stdin.gets.chop print 'password:' system 'stty -echo' pass = $stdin.gets.chop mm = MediaMarker.new(uname, pass) mm.login asin_list.each do |asin| mm.register(asin) end
Bookboard.rb
require 'rubygems'
require 'mechanize'
require 'logger'
class Bookboard
@uname
@pass
@agent
@log
def initialize(uname, pass)
@uname = uname
@pass = pass
@agent = WWW::Mechanize.new
@log = Logger.new(STDOUT)
end
# log in
def login
@log.info("logging in")
@agent.get('http://www.bookboard.jp/index.php')
@agent.page.form_with(:method => 'POST') {|f|
f.field_with('username').value = @uname
f.field_with('password').value = @pass
f.click_button
}
end
# get asin list by category
def asin_list_by_cat(num)
@log.info('getting asin list by category number');
asin_list = Array.new
@agent.get("http://www.bookboard.jp/index.php?categori=#{num}")
@agent.page.links_with(:href => /asin=/).each do |link|
asin_list.push link.href.match(/asin=([0-9A-Z]+)/)[1]
end
return asin_list
end
end
MediaMarker.rb
require 'rubygems'
require 'mechanize'
require 'logger'
class MediaMarker
@agent
@uname
@pass
@log
def initialize(uname, pass)
@agent = WWW::Mechanize.new
@uname = uname
@pass = pass
@log = Logger.new(STDOUT)
end
# log in
def login
@log.info('logging in')
@agent.get('http://mediamarker.net/login')
@agent.page.form_with(:name => 'login'){|f|
f.field_with(:name => 'uname').value = @uname
f.field_with(:name => 'pass').value = @pass
f.click_button
}
# todo: login failure process
end
# register asin
def register(asin)
@log.info("registering asin: #{asin}")
@agent.get("http://mediamarker.net/reg?cat=1&asin=#{asin}")
@agent.page.form_with(:name => 'reg'){|f|
f.click_button
}
end
end
2009-01-22
■ [RAILS]Agile Development with Rails 
- ビルダスタイルビュー
- ruby script/server すると rubygems が require できない旨のエラーが出る
- sudo gem update rails # Rails のアップデート
- "no such file to load -- sqlite3" が出た
- rubygems-update しなきゃいけないときがあるらしい
- データ定義言語(DDL)
- ADWR が mysql 使ってるので mysql 使うことにした
- Rails のバージョンが上がっていろいろ変わってるっぽいな
2009-01-21
■ [MAC]MacBook に Trac のインストール 
- ports からインストールした Trac
- datefmt.py と text.py でエラーが出るところを無理矢理 utf-8 を返すように修正
- 上記をやったら trac-admin /path/to/project initenv はできた
- けど、tracd --port 8000 /path/to/project したときに "Interpreter not initialized" という致命的なエラーが出てうまくいかなかった
- というわけで trac ja をインストール
- TracWebAdmin のインストール
- setuptools が必要らしいけどすでに入ってた
- WebAdmin ? The Trac Project から egg ファイルをダウンロードして、作成したプロジェクトの plugins ディレクトリにコピー
■ [DATABASE]MYSQL ユーザーの追加・削除 
- 追加
- GRANT ALL PRIVILEGES ON table_name.* TO username@hostname IDENTIFIED BY 'password';
- 削除
- SHOW PRIVILEGES;
- REVOKE GRANT OPTION ON table_name.* FROM username@hostname;
- DROP USER username@hostname;
参考
■ [MAC]Max OS X LeopardでAMP環境を構築しよう - Apache, MySQL, PHP, Perlで作る開発環境 - futomi’s CGI Cafe ![[http://www.futomi.com/lecture/macosx/index.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://www.futomi.com/lecture/macosx/index.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- ~/Sites/ の設定は /private/etc/users/username.conf でする
- てか /etc/apache2/users/username.conf と同じだった
- AddHandler cgi-script .cgi
- Options All
- AllowOverride All
- tail -f
- show columns from table;
■ [MAC]subversion のアップデート 
- port upgrade subversion
■ [UNIX][NETWORK] echoサービスのクライアント ![[http://www.coins.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-05-08/tcpip-client-echo.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://www.coins.tsukuba.ac.jp/~yas/coins/syspro-2000/2000-05-08/tcpip-client-echo.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- hostname
- telnet hostname 7
- $Header: hogehoge Exp $ みたいなやつ
■ [ABOUT]TODO 
- Capistrano
- Social Application
- send multipart mail by mail command
- study Selenium
- Pipes
- subversion's 'tag'
- SQL join
- twitter feed's date format (UTC+00:00?)
- on database dateformat
- suversion's pre and post commit
- Xpath know how
- OpenFastLadder Basic Authentication
■ [JAVASCRIPT] 
<html>
<head></head>
<body>
<h2>1</h2>
<p id="p1" onclick="click()">click</p>
<h2>2</h2>
<p id="p2">click</p>
<script type="text/javascript">
var flag = 0;
function click() {
if(flag == 1) { return; }
flag = 1;
}
p1 = document.getElementById('p1');
p1.appendChild(document.createTextNode('hoge'));
var myForm = document.createElement('form');
myForm.innerHTML = '<textarea></textarea><input type="submit" />';
console.log(myForm.innerHTML);
p1.appendChild(myForm);
</script>
</body>
</html>
2009-01-20
■ [RUBY]Regexp - Rubyリファレンスマニュアル ![[http://www.ruby-lang.org/ja/man/html/Regexp.html#match:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://www.ruby-lang.org/ja/man/html/Regexp.html#match:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- RegExp.union
■ [MAC]KeyRemap4MacBook を修正・ビルドしてインストール 
- 2008/11/05 - memo - unknownplace.orgの修正
- make
- できたパッケージをインストール
■ [MAC]MacBook に Trac をインストール 
- 乳牛日記: Trac mod_pythonで実行したら LookupError: unknown encoding: X-MAC-JAPANESE
- Genshi 0.5 再インストール + trac 0.11rc2 日本語版 — takanory.net
- 上記をやった後に easy_install -U Trac で trac-admin が動くようになった
■ [VIM]vim 
- :new
- :vnew
- :e
- :set noic 大文字小文字の区別をなくして検索
- :ls
- :bp
- :bn
- :b
- 画面分割後の操作 C-w jkhl / C-w
- C-r Redo
- V (ビジュアルモード)で範囲指定、y でコピー
■ [INTERFACE]一覧と詳細の中間 
一覧表示だといちいち個別のアイテムをリンクして見るのがめんどくさいし、詳細表示だと 1 画面に表示される情報量が少なすぎて物足りない。ぼくは一覧と詳細の中間のようなインターフェイスが欲しい。
ここまで考えて、「それって 2 ペイン構成にすれば解決するじゃん」とも思った(実際 Bloglines / Livedoor Reader のキーボード・ショートカットと 2 ペインの組み合わせによる読むためのインターフェイスは魅力的)。
でもそれは違って、RSS リーダーのように単純に最新のものから順に表示するときには 2 ペイン + キーボード・ショートカットでもうまく行くんだけど、もっと複雑な情報、リゾーム状の情報だとか深く階層化された情報(たとえば 1 つの Wiki にあるページ群)をアプリケーションのインターフェイスで表示するときは、そううまくはいかない。
自分の知ってる限り(かなり限りがある)では、TiddlyWiki と howm ぐらいかな(AutoPagerize も近いか)。まだまだいっぱいあるんだろうけど、「これが決め手」っていう感じのものはまだ出ていないように思う。
2009-01-19
■ subversion commands 
- svn st
- svn st -u
- svn up
- svn ci
- svn co
- svn ls [URL of repos]
- svn cat [URL of repos]
- svn log -r HEAD
- svn log -r 216
- svn diff -r 1:2
- svn diff -r 2
- svn propedit svn:ignore [path]
最初の作業
mkdir repos svnadmin create repos mkdir work echo 'hello' > work/test.txt cd work svn import file:///path/to/repos -m 'initial import'
■ [PHP][SECURITY]PHP と Web アプリケーションのセキュリティについてのメモ ![[http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html#PHP_Session:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html#PHP_Session:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- php.ini の session_autostart
■ [SECURITY]高木浩光@自宅の日記 - 駄目な技術文書の見分け方 その1 ![[http://takagi-hiromitsu.jp/diary/20061104.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://takagi-hiromitsu.jp/diary/20061104.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- セカンドオーダー SQL インジェクション
- 引用「セカンドオーダー云々なんてどうでもいいの。普通の開発者は覚えなくてよい用語。これは攻撃手法の用語であって、間違った方向性の対策がされているときにのみ意味のある話で、はじめから正しい対策を理解すればよいだけの話。 」
- 引用「マスコミの記事でよく見かける表現に、「完全に○○ないわけではない」というものがあるが、これは断定できないことを言うときの逃げ口上だってことを知っておいたほうがよい。マスコミには許されるが、技術文書には許されない。技術文書なら、前提を明らかにした上でその前提の上で何が言えるかを書くのであって、例外があるなら例外を書くようにする。」
■ 高木浩光@自宅の日記 - 続・「サニタイズ言うなキャンペーン」とは ![[http://takagi-hiromitsu.jp/diary/20060115.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://takagi-hiromitsu.jp/diary/20060115.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- Perl、Taint 機能
2009-01-18
■ 高木浩光@自宅の日記 - プログラミング解説書籍の脆弱性をどうするか, 「サニタイズ言うなキャンペーン」とは何か, ASPとかJSPとかPHPとかERBとか、逆だ.. ![[http://takagi-hiromitsu.jp/diary/20051227.html#p02:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://takagi-hiromitsu.jp/diary/20051227.html#p02:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- id や postdate はエスケープの必要がないけど、「問題を局所的にとどめる」という観点から htmlspecialchars に通すべき。無駄な処理かもしれないけど、前述の観点を優先して富豪的にプログラミングする
- HTML に文字列を出力するときは、エスケープ用の関数を使うのがデフォルトという考え方。セキュリティ云々の話ではなくて、「問題を局所的にとどめる」という考えから。これを守っていればセキュリティの問題もそもそも起こらない
- 引用「とりあえず「サニタイズ」も「エスケープ」も口にしないようにしてみたらよい。」
- magic_quote_gpc はデフォルトで OFF にしておくべき
- stripslashes
2009-01-17
■ 「サニタイズ言うなキャンペーン」私の解釈 ![[http://kmaebashi.com/zakki/zakki0042.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク [http://kmaebashi.com/zakki/zakki0042.html:title] - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- prepared statement/パラメタライズドSQL ← どこかに標準みたいのがあるんだろうか
- 引用「だからこそ、入力の段階でシングルクォートをエスケープしてしまうPHPのmagic quoteや、 HTMLでエスケープしなければならない文字を(デフォルトでは) 入力の段階で弾いてしまうASP.NETは、そもそもその発想からして間違っている、と私は思う※1。」
- 引用「プログラミングにおいてたいていの問題は「層を積み重ねる」ことで解決されてきた。」
- 引用「セキュリティ云々を考えなくても、通常のアプリケーション設計の発想で「できるだけきれいな世界にいられるように」書いていけば、自然に達成できるはずのことである。 」
- magic_quote について調べる
2009-01-16
■ [HTTP][Studying HTTP] Message Bodyを読む ![[http://www.studyinghttp.net/body:title]を読む - 何か作りながら書くメモ (tily) を含むブックマーク [http://www.studyinghttp.net/body:title]を読む - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- Message = start-line (= request-line or status-line) + HTTP Header + Message Body
- 転送コーディングって何 http://www.studyinghttp.net/body#Transfer_Codings
- IANA - ポート番号とか Content-Type を管理している機関
- Content-Type → メディアタイプ
- メディアタイプ、x-がついてるものは IANA に登録されていないもの
- ファイルのアップロード時には、multipart/form-data が用いられる
- 差分エンコーディングって実際使われているのかな
2009-01-15
■ [HTTP]ステータスコードについて理解を深めるために[Studying HTTP] HTTP Status Codeを読む ![ステータスコードについて理解を深めるために[http://www.studyinghttp.net/status_code:title]を読む - 何か作りながら書くメモ (tily) を含むブックマーク ステータスコードについて理解を深めるために[http://www.studyinghttp.net/status_code:title]を読む - 何か作りながら書くメモ (tily) を含むブックマーク](/images/b_entry_bl.gif)
- 「ステータスコード」
- 1xx:Informational/2xx:Success/3xx:Redirection/4xx:Client Error/5xx:Server Error
- xx の部分に分類ルールはない
- 'Not Found' とかは Reason Phrase と呼ぶ
- SMTP の 250 とかはステータスコードとは呼ばない?
- 2 系の違いって?
- とりあえず1~5の大まかな意味合いを理解する
- 207 Multi-Status 面白い
- 301 Moved Permanently ではレスポンス内の Location フィールドによって与えられるべき
- 「フィールド」
- 301 は http://www.studyinghttp.net/example のように example がディレクトリなのに / をつけない場合に返される
- POST でリクエストしたのに GET にリダイレクトしたい場合、メソッドが変わるので、302 ではなくて 303 See Other を使うべき
- WEBRick とか lighttpd とかどこまでこれを実装してるのだろうか
- サーバー書いてみたくなる
- Content-Length http://www.studyinghttp.net/header#Content-Length
- [Studying HTTP] Message Body
- 504 Gateway Timeout と 4xx Request Timeout なんちゃらは違うものなのか
2009-01-13
2007-12-18
■ [Perl][NLP]Debian SargeにMeCabとText::MeCab(Perlモジュール)をインストール 
apt-get install mecab apt-get install libmecab-dev cpan install Text::MeCab
apt-getでmecabをインストールしたあとに、cpanシェルでText::MeCabをインストールしようとすると、mecab-configというコマンドが見つからなくて中止になってしまう。
いろいろ調べたんだけど、Debianの場合MeCabパッケージ本体にはmecab-configが含まれておらず、libmecab-devに入っているようだ(参照: [SpamAssassin-JP 336] Re: Debian Package => SpamAssassin-3.1.4日本語対応パッチ(案、その5) )。
■ [Perl][NLP]MeCabを使ってみる 
[を] Text::MeCabは導入が楽に出ているプログラムのテキストを変えて動かしてみただけ。
リスト:
#! /usr/bin/perl
use Text::MeCab;
my $m = Text::MeCab->new();
my $str_euc = "何の幸せの人格についてなら11回分だろう、君は冷凍庫のトラックは既に文章の犬。";
my $n = $m->parse($str_euc);
while ($n = $n->next) {
printf("%s\t%s\t%d\n",
$n->surface,
$n->feature,
$n->cost
);
}
出力結果:
何の 連体詞,*,*,*,何の,なんの,代表表記:何の 4108
幸せ 形容詞,*,ナ形容詞,語幹,幸せだ,しあわせ,代表表記:幸せだ 11380
の 助詞,接続助詞,*,*,の,の,* 18649
人格 名詞,普通名詞,*,*,人格,じんかく,代表表記:人格 23766
に 助詞,格助詞,*,*,に,に,* 27984
ついて 動詞,*,子音動詞カ行,タ系連用テ形,つく,ついて,代表表記:就く 32369
なら 助詞,接続助詞,*,*,なら,なら,* 36676
11 名詞,数詞,*,*,*,*,* 49399
回 接尾辞,名詞性名詞助数辞,*,*,回,かい,* 51748
分 接尾辞,名詞性名詞助数辞,*,*,分,ふん,* 56084
だろう 判定詞,*,判定詞,ダ列基本推量形,だ,だろう,* 62377
、 特殊,読点,*,*,、,、,* 56835
君 名詞,普通名詞,*,*,君,きみ,漢字読み:訓 代表表記:君 64844
は 助詞,副助詞,*,*,は,は,* 66819
冷凍 名詞,サ変名詞,*,*,冷凍,れいとう,代表表記:冷凍 73760
庫 名詞,普通名詞,*,*,庫,こ,漢字読み:音 代表表記:庫 80307
の 助詞,接続助詞,*,*,の,の,* 83274
トラック 名詞,普通名詞,*,*,トラック,とらっく,代表表記:トラック 89267
は 助詞,副助詞,*,*,は,は,* 91242
既に 副詞,*,*,*,既に,すでに,代表表記:既に 96904
文章 名詞,普通名詞,*,*,文章,ぶんしょう,代表表記:文章 104661
の 助詞,接続助詞,*,*,の,の,* 107628
犬 名詞,普通名詞,*,*,犬,いぬ,漢字読み:訓 代表表記:犬 112763
。 特殊,句点,*,*,。,。,* 109395
BOS/EOS,*,*,*,*,*,* 109179
2007-12-17
■ Favotterから直接FavするグリモンをAutoPagerize対応にしようとしてるんだけどうまくいかない 
■ 人工無脳を作るのに参考になりそうな書籍・サイト 
- 2007-11-24 - phaのニート日記
- 人工無能を作ろう〜RSSからマルコフ連鎖(php)
- 作者: 秋山智俊
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2005/04
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 78回
- Amazon.co.jpで詳細を見る
- マルコフ連鎖で文章生成(JavaScript) - エブログ
2007-12-01
■ Favotterに直接favするボタンをつけるGreaseMonkeyスクリプト 
<追記>
os0xさんがMinibuffer用のTwitter Post & Favコマンドを作られたので、そっちのほうを使ったほうがいいです。
http://d.hatena.ne.jp/os0x/20071201/1196460723
以下のスクリプトはあくまで勉強用に作ったものなので、信頼性が低いです。
</追記>
<追記2>
ふぁぼったーの仕様変更で動かなくなっていたのですが、jt_noSkeさんが修正して動くようにしてくれました。ここに載せている「インストール」リンクと、ソースコードにも反映しておきました。Tnx!
</追記2>
かなり動作がもっさりしてるんだけど、一応作ってみた。
FavotterでFavってない発言があると、日時表示の右に「Favに追加」という文字が出る。
「Favに追加」という文字をクリックすると、自分のFavに追加するリクエストが始まる。
追加が終了すると、「Fav済」という文字に変わる。
ダメっぽいところ:
- 正規表現使ってるところが多くてソースが汚い
- document.evaluateを2回使ってるんだけど1回に減らせるのだろうか
- AutoPagerize非対応
どんどんダメ出しお願いします。
// ==UserScript== // @name Favotter Direct Fav // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @include http://favotter.matope.com/* // ==/UserScript== (function (){ var attr_links = document.evaluate("//div[@class='info meta entry-meta']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for(var i = 0; i < attr_links.snapshotLength; i++) { var l = attr_links.snapshotItem(i); l.innerHTML.match(/<a title="[^"]*" href="([^"]*)">/); var status_url = RegExp.$1; l.innerHTML.match(/<a class="taggedlink" href="status\.php.*?(\d.+)">/); var status_id = RegExp.$1; status_url = status_url + "/statuses/" + status_id; make_link(status_url, status_id, i); } function make_link(status_url, status_id, num){ GM_xmlhttpRequest({ // confirm whether already faved or not method: 'GET', url: status_url, onload: function(res){ if(res.responseText.match(/icon_star_full/)){ }else if(res.responseText.match(/icon_star_empty/)){ _make_link(status_id, num); }else{ // Not Logged in to Twitter } } }); } function _make_link(status_id, num){ var attr_links = document.evaluate("//span[@class='xfolkentry']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var l = attr_links.snapshotItem(num); l.innerHTML = l.innerHTML.replace(/(\d+ fav by)/, '<span id="add_' + status_id + '_to_fav">Favに追加する</span> ' + RegExp.$1); var span = document.getElementById('add_' + status_id + '_to_fav'); span.addEventListener( 'click', function(){create_fav(status_id)}, false ); } function create_fav(status_id){ GM_xmlhttpRequest({ method: 'GET', url: 'http://twitter.com/favourings/create/' + status_id, onload: function(){ span = document.getElementById('add_' + status_id + '_to_fav'); span.innerHTML = "fav済"; } }); } })();
2007-11-23
■ 学習のしかたについて 
最初は人のコードを読んだり参考にしたりしながら、じょじょに自分のコードを書けるようになっていく、というのは結構あるっぽい。
あと「読んだり参考にしたり」とはちょっと違うけど、自分の目的にとって本質的ではないコードについては「コピペ」するのもあり。
もちろん、最初はただコピペした内容でも、あとからちゃんと読んで理解することが必要だ。
■ [JavaScript][GreaseMonkey]JavaScriptでの形態素解析についてメモ 
- munotterでは、外部の形態素解析エンジンを使用せずに「漢字・ひらがな・カタカナ・アルファベット・全角アルファベット・アスキー文字記号・全角記号・スペース」を単語の区切りとしている(L116-125)。
GamMo.prototype.pattern = {
"kanji": "([一-龠々〆ヵヶ]+)",
"hiragana": "([ぁ-ん]+)",
"katakana": "([ァ-ヴー]+)",
"word": "([a-zA-Z0-9_]+)",
"zenkaku": "([a-zA-Z0-9]+)",
"ascii": "([!-~]+)",
"kigoh": "([、。!?()「」『』’”!-\/:-@\[-\^`\{-~])",
"space": "([ \\s\\n]+)"
};
一番てっとり早い日本語形態素解析の方法ではあるけど、たとえば「わたしはかなしい」のような文が一つの形態素として解釈されてしまったり、逆に「冷やし中華」が「冷」と「やし」と「中華」の3つの形態素に分解されてしまう。
- GreaseMonkeyでは、GM_XMLHttpRequestからYahoo!形態素解析APIを利用することができる。
- HTML+JavaScriptでは、XMLHttpRequestに制限があるためできない。Yahoo!形態素解析APIがJSONPに対応したとしても、JSONPにはPOSTが無いからダメ(参考:Javascriptでdiffる ( with 形態素解析 ) (nakatani @ cybozu labs))。
とりあえずGreaseMonkey + Yahoo!形態素解析APIを試してみようかな。
korn_freakこんなのありますよ
http://chasen.org/~taku/software/TinySegmenter/
すごい
2007-11-22
■ [GreaseMonkey]Twitter Text Cutupを書いたあとのまとめ 
Twitterの発言をカットアップするGreaseMonkeyスクリプト - 何か作りながら書くメモ (tily) - はてな自習室
- String#replaceは破壊的メソッドじゃない
- いらないところでinnerHTMLを使ってるのであとで直す
- 「プログラミング作法」にしたがってスタイルを直す
- shuffleの話、最速インターフェース研究会 :: 実践JavaScriptで配列をシャッフルする方法リファクタリングにも書いてあった。あとで読む
- Yahoo!形態素解析APIを使ってみる
- SITEINFOもどきを作ってみたい
- とにかくGM_XMLHttpRequestを使ったスクリプトを書いてみる
■ [HTML]5分でどれだけ多くのHTML要素を挙げられるか 
- http://www.justsayhi.com/bb/html_quiz via otsune
43 elements remain
Named so far:
A, B, BLOCKQUOTE, BODY, BR, CITE, CODE, DD, DEL, DIV, DL, DT, EM, FIELDSET, FONT, FORM, H1, H2, H3, H4, H5, H6, HEAD, HTML, I, INPUT, LEGEND, LI, LINK, META, OL, P, PRE, Q, S, SCRIPT, SPAN, STRIKE, STRONG, STYLE, TABLE, TBODY, TD, THEAD, TITLE, TR, U, UL,
You forgot:
ABBR, ACRONYM, ADDRESS, APPLET, AREA, BASE, BASEFONT, BDO, BIG, BUTTON, CAPTION, CENTER, COL, COLGROUP, DFN, DIR, FRAME, FRAMESET, HR, IFRAME, IMG, INS, ISINDEX, KBD, LABEL, MAP, MENU, NOFRAMES, NOSCRIPT, OBJECT, OPTGROUP, OPTION, PARAM, SAMP, SELECT, SMALL, SUB, SUP, TEXTAREA, TFOOT, TH, TT, VAR,
■ もくもく会 
最初タバコ吸う人たちの集まりかと思った。
■ 知らないことが多すぎて恥ずかしい 
2007-11-21
■ [GreaseMonkey]Twitter Append To-iu LifeHack ver.2 
Twitter Append dead word from shigo.comのソースを見ながら、発言をsubmitするときにも「というライフハック」をつけるようにした。
勉強になったのは下記の3点:
- 既存のsubmitボタンにグリモンから新しいアクションを追加するやり方
- window / unsafeWindow判定の定型文
- unsafeWindowでgetElementByTagName()
// ==UserScript== // @name Twitter Append To-iu LifeHack // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @include http://twitter.com/* // ==/UserScript== (function() { var append_word ="というライフハック"; statuses = document.evaluate("//span[@class='entry-title entry-content']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for(var i = 0; i < statuses.snapshotLength; i++) { s = statuses.snapshotItem(i); s.innerHTML += append_word; } var onclick_orig; var w = (typeof unsafeWindow == 'undefined') ? window : unsafeWindow; var submit = w.document.getElementsByClassName('update-button')[0]; var onclick = function() { document.getElementById('status').value += append_word; submit.onclick = onclick_orig; submit.click(); submit.onclick = onclick; return false; } onclick_orig = submit.onclick; submit.onclick = onclick; })();
SEE ALSO:
■ [読書]「まるごとJavaScript」の「ものぐさなGreaseMonkeyの飼い方」を読んでいる 
■ [GreaseMonkey]Twitterの発言をカットアップするGreaseMonkeyスクリプト 
すでにタイムラインにのっているすべての発言をカットアップ。
カットアップ前:
しょぼいスクリプトでも人に使ってもらってるの見るとうれしい!というライフハック カセット!!!
Twitter / tily
カットアップ後:
リプトでもライフハック人に使ってもらょぼいスクセという カ見る とうれしい! し ット!!! ってるの
// ==UserScript== // @name Twitter Text Cutup // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @include http://twitter.com/* // ==/UserScript== (function() { var split_char_max = 7; // lucky seven var statuses = document.evaluate("//span[@class='entry-title entry-content']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for(var i = 0; i < statuses.snapshotLength; i++){ s = statuses.snapshotItem(i); s.innerHTML = s.innerHTML.replace(/<a.*?>(.*?)<\/a>/g, "$1"); s.innerHTML = cutup_text(s.innerHTML); } function cutup_text(text){ var array = []; while(text.length > 0){ var randnum = Math.floor(Math.random() * split_char_max + 1); var fragment = text.substr(0, randnum); array.push(fragment); text = text.substr(randnum, text.length); } shuffle(array); return array.join(""); } function shuffle(list) { var i = list.length; while (--i) { var j = Math.floor(Math.random() * (i + 1)); if (i == j) continue; var k = list[i]; list[i] = list[j]; list[j] = k; } return list; } })();
fubaさんのPerlスクリプトが面白いと思ったので、似たようなことをGreaseMonkeyでやってみた。
fubaさんみたいにMeCabで形態素解析とかはしてなくて、
- ランダムに1文字から7文字の間で分ける
- 配列にする
- shuffleする
- joinする
という流れ。GANTZの宇宙人がしゃべる言葉みたいになる。
ゆくゆくはYahoo!形態素解析APIを使って形態素に分けてfubaさんのやっているようなアルゴリズムも試してみたい。
あと、LDRize SITEINFO Wikiの情報を流用して、Twitterだけじゃなく主だったサイトをカットアップとかも勉強用に試す。
SEE ALSO:
- glitch20071121.pl - fubaはてな
- PARAGRAPHS
- hail2u.net - Weblog - JavaScriptで配列をシャッフル - shuffle関数をそのまま使ってしまったので万が一問題があったら教えていただけるとたすかります
2007-11-20
■ [GreaseMonkey]わかったこと 
- (function(){...}());は他のスクリプトと名前空間がかぶらないように使う
- XPathをどんな風につかうのかなんとなくつかんだ
- ASCII文字以外の文字列をハードコードする場合、UTF8を使わないと文字化けする
■ [GreaseMonkey]疑問 
- document.evaluate()の引数にとらせるものがよくわかってない(XPath自体を少し勉強しなければ)
- ORDERED_NODE_SNAPSHOT_TYPE以外のXPathResultのプロパティはどういうときに使うのか
■ [GreaseMonkey]やりたいこと 
- Twitter Append To-iu LifeHackに、発言をsubmitしたときに自動で語尾に「というライフハック」をつける機能も追加してみる
- Twitter Append To-iu LifeHackに、元の発言に「というライフハック」が入ってたら何もしない、という条件判定を追加する
- もうありそうだけど、Twitterの自分のfavをTumblrにQuoteするグリモン
- 前にQuoteしたTwitterのstatus IDを覚えておいて、重複してQuoteしないようにする
- Quoteずみの発言は灰色にするとか
- Twitterのstatusにチェックボックスをつけて、Quoteしたい発言を選べるようにする
- やっぱりLingr + MMLで音を使ってチャットできるグリモンを書いてみたいなぁ
2007-11-19
■ [プログラミング作法を読む]プログラミング作法を読む 
「プログラミング作法」を読んでいるんだけど、いちいち納得するのに頭からすり抜けていく感じがするので、メモ。
とりあえず重要なところを抜粋するという感じだけど、あとで自分なりの言葉で説明を入れるかも。
本のコード例がC/C++/Javaなので、Perl/Ruby/JavaScriptに書き換えるのも面白そう。
■ [プログラミング作法を読む]スタイルについて(1) 名前 
グローバルにはわかりやすい名前を、ローカルには短い名前をつける
統一する
関数には能動的な名前をつける
基本的にはgetTime()のように能動的な「動詞+名詞」の名前をつける。
真偽値を返す関数にはisOctal()みたいにisで始まる名前を付ける。
的確に名前をつける
■ [プログラミング作法を読む]スタイルについて(2) 式と文 
構造がわかるようにインデントする
自然な形の式を使う
かっこを使ってあいまいさを解消する
複雑な式は分割する
明快に書く
副作用に注意する
■ [プログラミング作法を読む]スタイルについて(4) 関数マクロ 
関数マクロはLLには無い(よね?)のでとりあえず読み飛ばしてもいいかな。
関数マクロはなるべく使わない
マクロの本体と引数はかっこに入れる
■ [プログラミング作法を読む]スタイルについて(5) マジックナンバー 
マジックナンバーには名前をつける
数値はマクロではなく定数として定義する
整数ではなく文字定数を使う
オブジェクトサイズは言語に計算させる
■ [プログラミング作法を読む]スタイルについて(6) コメント 
当たり前のことはいちいち書かない
関数とグローバルデータにコメントする
悪いコードにコメントをつけない。書き直す
コードと矛盾させない
混乱を招かないようにあくまでも明快に書く
- 作者: ブライアンカーニハン, ロブパイク, Brian Kernighan, Rob Pike, 福崎俊博
- 出版社/メーカー: アスキー
- 発売日: 2000/11
- メディア: 単行本
- 購入: 18人 クリック: 165回
- Amazon.co.jpで詳細を見る
The Practice of Programming (Addison-Wesley Professional Computing Series)
- 作者: Brian W. Kernighan, Rob Pike
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 1999/02/04
- メディア: ペーパーバック
- クリック: 4回
- Amazon.co.jpで詳細を見る
■ [GreaseMonkey]編集画面を開いたら自動で「ちょっとした更新」にチェックするGreaseMonkey 
// ==UserScript== // @name Check Trivial // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @description Automatically check "trivial update" checkbox // @include http://d.hatena.ne.jp/* // @include http://*.g.hatena.ne.jp/* // ==/UserScript== document.getElementById("trivial").checked = true;
■ [GreaseMonkey]Twitterのすべての発言に「というライフハック」をつけるグリモン 
Twitter / eigokun
おれも作ってみた。XPathはじめて使った。
// ==UserScript== // @name Twitter Append To-iu LifeHack // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @include http://twitter.com/* // ==/UserScript== (function() { statuses = document.evaluate("//span[@class='entry-title entry-content']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for(var i = 0; i < statuses.snapshotLength; i++){ s = statuses.snapshotItem(i); s.innerHTML = s.innerHTML + "というライフハック"; } })();
うざくなってすぐ消した。
SEE ALSO: 4.6. Doing something for every element with a certain attribute [Dive Into Greasemonkey]
2007-11-18
■ [GreaseMonkey]Hello, World 
// ==UserScript== // @name Hello World // @namespace http://studyroom.g.hatena.ne.jp/tily/ // @description alert "Hello world!" on every page // @include * // ==/UserScript== alert('Hello World');

たぶんこれで動くと思います。
function make_link までのところを以下のコードに置き換え
(function (){
{
var attr_links = document.evaluate("//div[@class='info meta entry-meta']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i = 0; i < attr_links.snapshotLength; i++) {
var l = attr_links.snapshotItem(i);
l.innerHTML.match(/<a title="[^"]*" href="([^"]*)">/);
var status_url = RegExp.$1;
l.innerHTML.match(/<a class="taggedlink" href="status\.php.*?(\d.+)">/);
var status_id = RegExp.$1;
status_url = status_url + "/statuses/" + status_id;
make_link(status_url, status_id, i);
}