JSの設定

ラベル ruby の投稿を表示しています。 すべての投稿を表示
ラベル ruby の投稿を表示しています。 すべての投稿を表示

2012年4月22日日曜日

Ruby Programmer Gold の試験を受けて

1ヶ月前に紀伊半島一周しながらRubyの試験勉強してた時からだいぶ時間がたってGoldの受験となった。本当はSilverを受ける前にGoldを受けようと考えていたのだが、ずっと発売延期となっていた『Ruby公式資格教科書 Ruby技術者認定試験Silver/Gold対応』が発売されたことを知りこれを読んでから受験することにした。4/21のtwitterログから引用する。
Ruby技術者認定試験Gold、終了。76点でギリギリ合格。厳しい時間だった…公式資格教科書についてる模擬試験より全然むずいじゃんか。 
50問中、12も間違えたわけだ。どこを間違えたのか、3つくらいの心当たりしかないが…しかし、12間違えても合格なのだから、完璧主義は封印して、自信ない問題には早々に見切りをつけたほうが良かったかもしれない。  
一画面に収まらない長文の問題は後回しにしたが、結局それらを解くだけで90分使ってしまい、全体の確認に時間を残せなかった。4択で、正しいものを全て選べ系の難問に迷うよりは、一つしか正解がない問題をたくさん見直すほうが率が良い。しかし、一問目が一番難しいのには痺れた。 
 ちなみにSilverのほうは50問中47問正解で、簡単だった。公式資格教科書だけで十分いける。Ruby技術者認定試験Goldにチャレンジする人は、まずこちらでPC受験の独特の雰囲気と時間配分に慣れてから受けることをオススメしたい。 
3問間違いと12問間違いの間には9問の差があるが、感覚としてそのうち4問くらいは確認に残せた時間の差という気がする。そしてもう少し言えば、長文に出くわした時にそれが単に長い問題なのか本当の難問なのか見極める即時的判断力があると、後回しにするというオーバーヘッドを減らせたと思う。 
試験場にあるPCの画面解像度が低いので、長文問題だとスクロールしないと回答の選択肢が見えず嫌らしいが、そこは慌てずサッと回答に目を通したほうが良さそうだ。即時的難問判断に必要なスクロール。 
90分の持ち時間は長いようだが、問題全体の見通しの悪さと、ディスプレイにペンで書き込みが出来ない点、残り時間のカウントダウンが刻々と表示されて焦らさせる点などを考えると全く油断できない。シルバーのほうも最後のアンケートを入力し終わったらほとんど時間残らなかった。
 Ruby技術者認定試験は持ち時間90分、CBT(Computer Based Testing)と言われるコンピュータ試験、50問の選択式で合格ライン75%となっている。だから76点はまさにギリギリで、あと1問まちがえればアウトだ。貴重品等を入れるロッカーの鍵番号と同じ番号の席に座り受験番号を入力してスタートボタンを押せばテスト(と持ち時間のカウントダウン)が始まる。持ち時間が切れると容赦無くテストが終了し、同時に点数と合否が表示されるという味わいのないシステムである。「合格」の文字の前に「不」がついてないか2度見した。

やっぱり、紙に比べれば明らかに試験はやりにくい。上記ログでいうところの即時的難問判断も全部の問題がバッと見渡せたほうがラクだし、問題文の近くにメモを書けるのもメリットだ。CBTではメモ用紙は配られるもののペンが太いマジックで書きにくいし問題文が書いてないからメモする量が増える。例えばX行目の変数の内容を書くのに、問題用紙に書けるなら変数の内容だけで済むところを、まっさらなメモ用紙には変数名も書かなければならない。

まぁしかしそのへんの条件は皆同じわけで、要はそういうやりにくさがあるということを事前に知っておき対策を立てられたらベターということだ。で肝心の内容のほうは、あーありがち、技術メモ、basyura’s blogなどにある通りでRubyという言語の本質を突いた良問が多い印象。読んで役にたったと思う本は『Ruby公式資格教科書 Ruby技術者認定試験Silver/Gold対応』の他は『メタプログラミングRuby』のみ。ITトレメの問題は模擬試験の品質を備えていない。

また出題範囲が1.8.7なので下手に1.9系の本を読まないほうがいい、例えばプログラミング言語 Rubyとか良書だがスコープを超えすぎる(※混乱しない自信があれば有益ではある)。『メタプログラミングRuby』も、メタプログラミングの魅力に取り憑かれるのは後回しにしてメソッド探索のルートやスコープの基礎論を重点的に、irbも使いつつ読み込んだほうがいい。

それと以下も重要。入れ子になったクラスのそれぞれで下記3種変数の宣言をしたり代入をしたり参照したりでどうなるか確認する。
「クラス変数とクラスインスタンス変数とインスタンス変数の違いについて - 遅咲きのエンジニア」
http://d.hatena.ne.jp/kabakiyo/20080525/1211728832

その他、トップレベルとか。
「Rubyのトップレベルのメソッドの不思議 - As Sloth As Possible」
http://blog.livedoor.jp/faulist/archives/1222830.html

enum_forとか。
「Rubyist Magazine - 標準添付ライブラリ紹介 【第 5 回】 enumerator」
http://jp.rubyist.net/magazine/?0011-BundledLibraries
「イテレータを便利にするenum_for - Slow Dance」
http://d.hatena.ne.jp/LukeSilvia/20081113/p1

ところでこの試験、プラチナも策定中みたいです。受かる自信がない。

2012年1月28日土曜日

SinatraとSequel・Hamlで掲示板アプリを作る そしてHerokuへあげる

WEB+DB Press Vol.65「Write Less, Do More」のコラムから引用:
(Railsの進化によって)Rubyの記述量がどんどん削減された結果、今度はそれ以外のコードがネックになってきたと言えるでしょう。だから次はRuby以外のコードをあまり書かなくていいようにと、SCSSやCoffeeScriptが取り込まれたのでしょう
ネックになってきたというか、なんでrubyは綺麗に書けるのにHTMLとかCSSとかこんな冗長にしか書けないんだという不満が潔癖症のプログラマを動かしたように思う。まぁ、haml・coffee・scssを導入したらしたで、新しい書き方が3つ増えるわけで、一人でやる分にはいいけどチームで開発する時どうなんだという気がしないでもないが・・・やはり目先の学習コストに対する寛容さは人それぞれだと思うし。

それはそれとして、以下のアプリはHamlとsassのイージーサンプルとなっているので掘り起こしてみた。

Ruby Freaks Lounge:第9回 SinatraとSequel・Hamlで掲示板アプリを作る|gihyo.jp … 技術評論社
http://gihyo.jp/dev/serial/01/ruby/0009

上の通り、公開されてるコード( http://github.com/yhara/sinatbbs/tree/magazine )をとってきて動かせばローカルで掲示板アプリがサクっと動くが、Herokuで動かすには少し修正がいる。以下、その手順をメモ。

◯ファイル追加など
- Gemfile
 sinatra, haml, sequel, sqlite3, heroku をGemfileに書き、bundle install --path ./vendor/bundle としておく。

- start.rb 修正
 require './model/comment.rb' (./を先頭につける)
※
Ruby 1.9.2から$LOAD_PATHにカレントディレクトリが含まれなくなった - ぬいぐるみライフ(仮)
http://d.hatena.ne.jp/mickey24/20100907/1283869273

- comment.rb 修正
 Sequel.connect(ENV['DATABASE_URL'] || "sqlite://db/development.sqlite3")
※
デプロイ時も考慮して、DBへの接続は Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://my.db') という感じで書く必要あり。 - Lost+Found
http://d.hatena.ne.jp/Snaka/20090704/1246712748

- migration用ファイルの作成
 db/migrate/001_create_posts.rb
class CreateComments < Sequel::Migration
  def up
    create_table :comments do
      primary_key :id
      text :name
      text :title
      text :message
      timestamp :posted_date
    end
  end
end
- Rakefile作成
require 'rubygems'
require 'rake'
require 'sequel'
require 'sequel/extensions/migration'

namespace :db do
  desc "migrate database"
  task :migrate do
    DB = Sequel.connect(ENV['DATABASE_URL'] ||'sqlite://db/development.sqlite3')
    Sequel::Migrator.apply(DB, './db/migrate')
  end
end

- config.ru作成
require './start.rb'
run Sinatra::Application

※
Ruby Freaks Lounge:第23回 Rackとは何か(1)Rackの生まれた背景|gihyo.jp … 技術評論社
http://gihyo.jp/dev/serial/01/ruby/0023

◯ローカルで動かしてみる

# rake db:migrate
※sqliteなので不要だが、herokuで必要なので確認しておく
# rackup

◯Herokuで動かす

# git init
# git add ./
# git commit -am "<コメント>"
# heroku create <app名>
# git push heroku master
# heroku rake db:migrate
# heroku open

http://bbs-sp3.heroku.com/
完成。


参考サイト:
CSS拡張メタ言語「SCSS(Sass)」と「LESS」の比較 - (DxD)∞
http://dxd8.com/archives/217/

Ruby Sequel DBアクセスライブラリ - yshのメモ日記
http://d.hatena.ne.jp/yshgt/20080629/1214720897

herokuでsqliteなsequelつかうときのメモ - Lost+Found
http://d.hatena.ne.jp/Snaka/20090709/1247155835

sequelでmigration | ゆーすけぶろぐ
http://yusukezzz.net/blog/archives/1574

Sinatraの使い方 - ayaketanのプログラミング勉強日記
http://d.hatena.ne.jp/ayaketan/20111219/1324295283

2012年1月22日日曜日

Heroku で lokka

lokkaという、sinatra(軽量rails)上で動くcmsをHeroku(ruby版Paas)にアップする手順メモ。

◯環境

Mac OS X 10.6.8
MacPorts 2.0.3
rvm 1.10.2
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin10.8.0]
gem 1.8.15
heroku (2.18.1)
git version 1.7.7.4

◯環境構築手順

http://www.macports.org/install.php
macportsのインストール(略)
rvmのインストール(略)
rubyのインストール(略)
gitのインストール(略)

git clone git://github.com/komagata/lokka.git #lokkaを取得する
cp -p database.default.yml database.yml #lokkaディレクトリ内にdatabase.ymlを作成
bundle install ./vendor/bundle --without development postgresql #postgresを使わない設定
bundle exec rake db:setup
bundle exec rackup #ローカルでlokkaが確認できる

gem install heroku #ここからherokuにデプロイしていく
heroku create
git push heroku master #ssh公開鍵を作成しておく必要がある
heroku rake db:setup
heroku open #デプロイされたlokkaを確認できる

gem install taps #ローカルでlokka確認したときユーザ作成などしていたらDBをpushする
heroku db:push sqlite://db/development.sqlite3

◯できたもの
http://spinel3-lokka.heroku.com/

◯参考サイト

HerokuでWebアプリ開発を始めるなら知っておきたいこと (7)ブログならLokka - アインシュタインの電話番号☎
http://d.hatena.ne.jp/ruedap/20110505/ruby_heroku_web_app_development_tips_7

LokkaをインストールしてHerokuにデプロイした - kk_Atakaの日記
http://d.hatena.ne.jp/kk_Ataka/20111127/1322329546

HerokuでDBのデータをダウンロードしたりアップロードしたり - アインシュタインの電話番号☎
http://d.hatena.ne.jp/ruedap/20110222/ruby_heroku_database_sqlite3_download_upload

HerokuにWebアプリ(Sinatra)をデプロイする手順をまとめた - kk_Atakaの日記
http://d.hatena.ne.jp/kk_Ataka/20111126/1322240459

2010年7月11日日曜日

willcomのメールフィルタリングの不自由さを解決する

いかに、携帯(PHS)に残したいメールだけ(自動的にフィルタリングして)残すかという話。
willcomのメール設定では、fromアドレスを指定してメールの受信を拒否することができる。
アスタリスクが使えるので、例えば「*@*.com」みたいな条件を設定することができるが、
正規表現までは使えないので加減が難しい。そもそも、fromアドレスだけじゃなく本文もフィルタリング条件にしたい。

これを実現するために、知人には携帯アドレスではなく例えばGMailのアドレスを伝えることにし、そこに届いたメールは一旦全て自宅サーバに転送してしまい、思う存分フィルタリングをかけた上で好きなものだけ携帯に送るようにしてはどうか。間にGMailを挟むことで可用性が向上する上、第一フィルタリングをGMailで設定することによって自宅サーバの負荷を抑えられる。
メールの種類によって読む端末を分けたい場合にも有効で、GmailならiPadやiPhoneを初めとする無線LAN対応機器を使い通信料を発生させずに読むことができる。


「思う存分フィルタリング」のやり方。
だいたいここに書いてあることと同じだが、procmailrcの内容を以下のように変えている。これにより、メールソースを渡しつつfoward.rbを実行することができる。


MAILDIR=$HOME/Maildir/
DEFAULT=$MAILDIR
RubyDir=$HOME/scripts/ruby
TmpDir=$HOME/tmp/
LOGFILE=$MAILDIR/proc/`date +%Y-%m`.log
LOCKFILE=$HOME/.lock
VERBOSE=ON

:0 Hc :
* .
|cat > $TmpDir/mail; $RubyDir/forward.rb


メールソースをrubyで扱うのにtmailというライブラリが便利なのでこれを利用する。メールを送信するにはnet/smtpを使うが、認証がうまくいかなかったのでaction_mailerを使うことにした。
gem install tmail
gem install action_mailer

以下、forward.rb の例。


#!/usr/bin/ruby

require 'rubygems'
require 'action_mailer'
require 'tmail'
require 'kconv'

〜中略〜
mail = TMail::Mail.load(mail_path)
# 前述のprocmailrcの「cat > $TmpDir/mail」で保存した一時ファイルを指定している
subject = mail.subject
body = mail.body
〜中略〜

# 日本語文字化け対策つきメール送信メソッドの定義
class HogeMailer < ActionMailer::Base
@@default_charset = 'iso-2022-jp'
@@encode_subject = false
def hogeMessage(recipient, mySubject, myBody)
from 'from@from.com'
recipients recipient
subject '=?ISO-2022-JP?B?' + Kconv.tojis(mySubject).split(//,1).pack('m').chomp + '?='
body Kconv.tojis(myBody)
end
end


#認証とかの情報設定
ActionMailer::Base.smtp_settings = { :address => '127.0.0.1',
:port => 25,
:domain => 'XXX',
:user_name => 'XXX',
:password => 'XXX',
:authentication => :login}

#送信!
HogeMailer.deliver_hogeMessage('to@to.com', mail.subject, mail.body)


上記では単に転送しているだけだが、mail.fromやmail.bodyを正規表現などでフィルタリングしたあと
複数の宛先に投げ分ければよい。また、大量のスパムメールが直接携帯アドレスに届くような場合には、willcom側の設定で例えば「*.com」を拒否しておき、forward.rbの中でfromアドレスを「.com」→「.etc」のように書き換えた上で転送するなど、色々応用がきく。

2010年5月28日金曜日

ねづっちボット:現在の機能

お題をだしてもらってなぞかけ(?)をする


「@nezucchi_bot 競馬」などとお題を出す。
※単語じゃなく短い文章でも可。ツイッター検索で結果がでそうなら。

するとこんなリプライが届く。※10分以内に。

ととのいました! 競馬 とかけまして 欧州財政不安継続 とときます、その心は次のツイートで!(ATM:83%)

次のツイートはリプライでは届かない。ねづっちボットをフォローして、さっき届いたリプライの次にあるツイート(公式RT)を見よう。

ユーロ急落、8年半ぶり安値。世界株安連鎖。ダウ1万ドル割れ。欧州財政不安継続。長期投資家もユーロに見切り?いよいよ、今週末の競馬は、負けられない。土曜日に勝ちを確定させ、日曜日は東京競馬場で、史上最強メンバーの日本ダービーを生で観戦し、目黒記念で転がしたい。

「競馬と欧州不安にどんな関係があるんじゃい、と思ったが、なるほどそういうことだったのか」というのがねづっちボットの楽しみ方。ちなみにリプライ末尾にATM:83%とあるのは、

「あなたが選んだお題はどれくらいツイッターのトレンドにマッチしているか指数」の略。

お題でツイッター検索をした結果がたくさんあり、それらのツイートの中身がちゃんとしており(URLやハッシュタグやRTだらけでなく色々な品詞をバランスよく使って自分の言葉で語られている)・・・といったいくつかの条件から算出される。目指せ100%超え!

誰にも相手してもらえないと自分でなぞかけをする


はてなキーワードからお題を取得。
ととのいました! カンヌ国際映画祭 とかけまして 著名映画監督ジャファル とときます、その心は次のツイートで! (*カンヌ国際映画祭 got by: http://bit.ly/ciN5Fc ) 自己採点:80点

このように英語になることも。つぶやくのは毎時3分(1時間に1回)。
I riddle!Why is "Google Chrome" like "erschienen" ? The reason comes in next tweet ! (*Google Chrome got by: http://bit.ly/cXCqmz ) score:46

※ATM、自己採点、scoreは同じ指標。

参照:
ねづっちボットを作ることになった経緯と簡単な仕様説明

2010年5月26日水曜日

別のねずっちボット

3日くらい前、まおらんちという人達に声をかけられた。なんでも、ねずっちボットを作ろうとしていたらすぴー製ねずっちボットを見つけてしまったらしい。ログ

で、これがまおらんち製ねずっちボット。優劣を言うつもりは毛頭ないが、全く違った作りであることは確かなので良い比較対象ができた。まず第一に、ま製はなぞかけという実際の行為を忠実に再現しようとしていることが分かる。

例をひいてみよう。「東京」とかけて、「予定」と説きます。その心は、どちらも「かんこう(観光と刊行)」。これはつまり、東京観光と刊行予定という言葉があって、両方にかんこうという読みが共通して含まれているということだ。

次の例。「終電」とかけて、「土星」と説きます。その心は、どちらも「じこく(時刻と二黒)」。二黒土星(じこくどせい)とは、暦、占いに用いられる九星の一つ。このことを知っていれば意味が分かる。ざっとま製なぞかけを見渡すと、土星と二黒のように、すぐには関連性が分からないものも多い。このへんが課題か。

この発展形を考えるため、自分で作ったなぞかけから例をひく。
厚み とかけまして やり遂げる人 とときます、その心は どちらも意思(石)が強い。
厚みは囲碁の用語で、石が強いことを指す。やり遂げる人は意思が強いというのも、結局同じ意味のことを別の表現で言い換えている。A(厚み)もB(やり遂げる人)も、C(いしがつよい)という共通表現で言い換えることができますよ、というのがこのなぞかけである。

これを考える時の人間の(というか僕の)思考は、石が強い=厚み をまず思い浮かべる。次に「いしがつよい」を何か別の表現で言い換えられないかなと考え、「やり遂げる人」に辿り着く。もう少し詳しくいうと、「いし」はなぞかけに適した語だという認識が予め存在し、これを用いていてなおかつ言い換えが利きそうな文章として「いしが強い」を思い浮かべる。いしを「石」とした場合には「厚み」と言い換えられ、「意思」とした場合には「やり遂げる人」に言い換えられるが、もちろん一発で「いしが強い」を探し当てられるわけではもちろんなく、要は2通りに言い換え可能な表現につきあたるまで探索を繰り返す。

さらに詳しくみよう。まず、このなぞかけを作った時の状況では、お題は自分で自由にだすことができた。だから、「いし」のような特定のものを「自分の中の、なぞかけに適した語データベース」から適当に引っ張り出し、2通りに言い換え可能にするためには「いし」にどんな語をつなげればいいかを色々ためす。

では、お題を自分で選べない時(ねずっちのようにお客さんに出題される場合など)はどうか。
仮に「厚み」と出題されたとする。まずは厚みという語はどんな表現で言い換え可能なのか考える必要があるだろう。しかも言い換えられた表現の中に「なぞかけに適した語」がなければならない。

ということは、「なぞかけに適した語」それぞれと「厚み」という語の関連度を調べればいいのかもしれない。ウェブ検索によって「いし」と「厚み」は関連度が高いと判定されれば、あとはこの「いし」を起点に先ほど(お題を自分で出した時)と同様に2通り言い換え可能表現を探索する。ただしこの場合は片方の言い換えに制約条件がある。

次に、す製を検証してみよう。例をひく。

「桃屋 とかけまして 「鹿角らーゆ」 とときます、その心は次のツイートで!
RT 昨日「鹿角らーゆ」という食べるラー油の類似品食べた。かなり微妙。本家桃屋のは食べたことないけど、ぐーぐる先生曰く似たような味ということなので、食べるラー油ってこんなものなんだなあと思った。」

RT以下全体がこのなぞかけの心だ、意味は自分で読みとけ、と突き放しているのが良くも悪くもこのボットの特徴だ。もちろんこのパターンはあってもよいが、発展形を考えるならば、やはりもっと色々なパターンのなぞかけができるといいだろう。で、とりあえず何故現状す製はこのパターンを採用しているかといえば、ボットの制作難易度とユーザから見た時の面白さのバランスを図った、ということである。

そもそもなぞかけは、面白いものを作ろうと思ったら人間がやっても難しい。なので、面白くするためには人間のツイートを利用するのが手っ取り早いのだ。AとかけてBととく・・・その心がうまくなくても、AとBが登場するCというツイートが見えれば、ボットの心の動き(CのどこからAやBをひろったか、他の語をさしおいてBが選ばれたのは何故か)やC自体の面白さを楽しむことができる。

そういうわけで、ねずっちボットの制作には大きく2つの意味があると思う。1つは「生きた言語空間における自然言語の取り扱い技術、学習技術の習得」。もう1つは「面白さの追求」。どういうなぞかけに対して人間が面白いと思うのか、そのあたりを、実際に面白いなぞかけとつまらないなぞかけを並べてみて比較・分析したり、ま製パターン・す製パターン他にどのようなパターンがなぞかけの範囲の中で考えられるか検討したり。単なるOAuthの練習として始めた課題にしては意外に奥が深い。

2010年5月8日土曜日

ねづっちボットを作る

こういうわけで、7月からtwitterAPIを使うのにベーシック認証が使えなくなるのですね。

マイコミジャーナルではツイッターで記事につけたコメントを集めたまじつぶというサービスをやっとるんですが、「記事にコメントをつける」ところでベーシック認証を使ってる。なので代わりの方法であるOAuth(http://j.mp/arIIzhを参考にオォースと読むことにしてる)に切り替えないといけないんだけど何だかややこしい。ツイッターのボットでも作ってみたらいい演習になるんじゃない?と考えました。

どんなボットがいいかな〜と思って何週間か悩んでいたらテレビにねづっちがでていた。でツイッターに「ねづっちボットってあったら面白そう」と言ったら面白そうですねという反応があった( http://j.mp/9FMSIR http://j.mp/akKdff )のでやる気になりGWに作ることに。
※比較的最近使い始めたdeliciousのrubyタグはねづっちbot作成のための資料がほとんど

◯ねづっち作成方針

ー 大方針 ー
・@nezucchi_bot [お題] のように話しかけてもらい、[お題]でツイッターの世界を検索。全角文字がなるべく多く含まれるツイートを探し、これを[心]とする。[心]を、Yahooの形態素解析サービス( http://j.mp/abW6hx )を使って品詞単位に分割し、名詞だけを集める。この中から「全てひらがなでない・全て半角でない・[お題]とのレーベンシュタイン距離がなるべく遠い」という条件で候補を絞り、最終的に残ったものの中からランダムで[答え]を決定する。

こうして、「ととのいました![お題]とかけまして[答え]とときます、その心は[心]!」というなぞかけを完成させる。

・誰も話しかけてくれない時はお題を自分から探しにいく。はてなキーワードからランダムに1つを選択。

ー 小方針 ー
・一度答えたお題にそれ以降答えないようにするため、お題のツイートIDをDBに保存する。
・DBを簡単に利用するため、また、ActiveSupportの便利なモジュールを利用するため、Railsを使う。
・ボットはウェブアプリケーションではなくバッチで動かすので script/runner を使う。
・長いURLをポストする時は短縮する( bit.ly )

◯環境構築

まだあまり使いこなせていないMacの環境構築から始める。
OSバージョン:10.6.3
Core2 Duo, メモリ4GB
Rails : 2.3.5(初めからインストールされてた)
mysql : 5.1.46 http://j.mp/cOB7ch を参考に。64bit版じゃないと動かない
XCode : Cコンパイラとか。Mac付属のCDに入ってるらしいんだけどDLした( http://j.mp/cNzefy )
※Windowsの場合はVisual Studio 2008 Express Editionあたりをインストールすればよかろう。

・プロジェクトの作成

# rails nezubot --database=mysql
# cd nezubot
# ruby script/generate scaffold Nezubot postid:string user:string tubu:text
# vi config/database.yml -> adapter: mysql
# rake db:create
# rake db:migrate

・OAuthの準備をする
http://j.mp/9TbPyH を参考に4つのキーを取得する。

・短縮URLの準備をする
bitlyのAPIキーを取得しておく。

・Yahoo形態素解析の準備をする
yahooのAPIキーを取得しておく。

◯実装

長いので急所だけ。

#!/usr/bin/env ruby
# coding: utf-8

require 'json'
require 'rest_client'
require 'uri'
require 'oauth'
require 'pp'
require 'leven' # http://j.mp/awOXy6 を外部ファイル化

# URL短縮関数
def shorten(long_url)
 id = 'xxx'
 api_key = 'xxx'
 req = "http://api.bit.ly/v3/shorten?login=#{id}&apiKey=#{api_key}&uri=#{URI.encode(
long_url)}&format=json"

 json = RestClient.get req
 jhash = ActiveSupport::JSON.decode json
 jhash["data"]["url"]
end

# お題[q]から[心]を求める関数
def getBestres(q)
 bestres = []
 uri = "http://search.twitter.com/search.json?q=" + URI.encode(q) + "&locale=ja";

 begin
  json = RestClient.get(uri)
  jhash = ActiveSupport::JSON.decode(json)
 rescue
  abort("rescued in getjson")
 end

 if( jhash["results"] != [])
  jhash["results"].each{ |r|
   if( r["text"].gsub(/[ -~。-゚]*/,"").length > 200 )
    bestres = [r["id"],r["text"],r["from_user"],q ]
    break
   end

   bestres = [r["id"],r["text"],r["from_user"],q ] if bestres==[]
  }
 end

 return bestres
end #getBestres


# [心]から[答え]を決定する関数
def getBestnoun(bestres)
 yuri = "http://jlp.yahooapis.jp/MAService/V1/parse?appid=[API_KEY]&results=ma,uniq&uniq_filter=9|10&sentence="
 nounlist = []

 if( bestres != [] )
  yuri = URI.encode(yuri + bestres[1])
  yhash = Hash.from_xml RestClient.get(yuri)

  words = yhash["ResultSet"]["ma_result"]["word_list"]["word"]
  words.each{ |w|
   nounlist.push w["surface"] if w["pos"]=="名詞"
  }

# 名詞ではなくても、括弧類で囲まれた語は候補に加える
  nounlist.concat bestres[1].scan(/(「.*?」)|(\[.*?\])|(『.*?』)|((.*?))|(\(.*?\))/).
flatten
  nounlist.uniq!

# casecmpは全角半角無視で文字列同士を比べる
  nounlist = nounlist.select{ |i| (i=~/^[^ -~。-゚]*$/)==0 && !(i=~/^[ぁ-ん]*$/) && i.length
> 5 && i.casecmp(bestres[3])!=0 }

(中略)

 return nounlist.rand
end

# 取得した4つのキーを使ってOAuthの下準備をする
begin
consumer = OAuth::Consumer.new(
CONSUMER_KEY,
CONSUMER_SECRET,
:site => 'http://twitter.com'
)
access_token = OAuth::AccessToken.new(
consumer,
ACCESS_TOKEN,
ACCESS_TOKEN_SECRET
)
response = access_token.get('http://twitter.com/statuses/mentions.json')
rescue
abort("rescued in oauth.new")
end

# 出してもらったお題を処理してなぞかけを送信する
JSON.parse(response.body).each do |status|
 news = []
 postid = status['id']
 user = status['user']
 tubu = status['text'].gsub(" "," ")
 next unless (tubu=~/^(@|\.@|@)/)==0

 ActiveRecord::Base.cache do
  news = Spbot.find(:all, :conditions => ["postid = ?", [postid] ])
 end

 if( news==[] )
 begin
  q = tubu.split(' ')[1] || ""
  next if(q=="")
  bestres = getBestres(q)
  bestnoun = getBestnoun( bestres ) || "error:#{q}:できませんでした!(T-T)"

  ans = bestnoun
  ans = ".@#{user['screen_name']} ととのいました! #{q} とかけまして #{bestnoun} とときます、その心は次のツイートで!" if !ans.include? "error"

  if !$DEBUG
   access_token.post('http://twitter.com/statuses/update.json','status'=> ans )
   access_token.post("http://twitter.com/statuses/retweet/#{bestres[0].to_s}.jso
n") if !ans.include? "error"
  end
 rescue
  abort("rescued in postid:#{postid}")
 else
  Spbot.create(:postid => postid, :user => user, :tubu => tubu) if !$DEBUG
 end
end

end if ARGV[0] #JSON.parse

# 一人なぞかけは省略

◯定期実行
0 * * * * ( script/runner nezu.rb) # 一人つぶやき
*/10 * * * * ( script/runner nezu.rb reply) # お題に答える

◯完成品
http://twitter.com/nezucchi_bot

5/26 追記 別のねづっちボット