たろマーク (はてなブックマーク)
-
[ api ][ phone ][ webservice ]
- Colorful Bokeh Effect in Pixelmator | Abduzeedo | Graphic Design Inspiration and Photoshop Tutorials
[ pixelmator ] -
[ pixelmator ]
-
[ python ] 結構ボリュームあるw python のみならず、チームの開発サイクルとか、実際にどう活用していくかと言うことが書いてありそうで wktk
■ruby 1.8 の正規表現でバイト列じゃなくて文字列でマッチする
mobitaro のバックエンドに使い始めた Citrus で、IRC に貼られた URL にあるタイトルを表示する機能があるんですが、woremacx さんから、長いタイトルが変なところで区切られてるという指摘を受けて見てみた。
たとえばこんな感じ。
Ruby 1.9 で日本語(マルチバイト)の文字列を扱�... [text/html; charset=euc-jp]
結論から言うと plugins/http/default.rb の 89 行目、正規表現で60文字までマッチさせて ... をくっつけてるところを u フラグ立てるようにしたら解決。
if title.size > 70
title = title[/.{0,60}/u] + "..."
end
ruby 1.8系の正規表現は $KCODE の値に従うか、オプションをつけることで文字コードを指定できるみたい。
Ruby は日本語化されているので、$KCODE の値に従って正 規表現中の日本語文字を正しく扱います。$KCODE = "n" の場合、日本 語文字を一切認識せずにバイト列として扱います。これはデフォルトの動作で す。オプションとして n, e, s, u のいずれかを指定す ることで正規表現の文字コードを $KCODE の値に関係なく 個々の正規表現リテラルに指定することもできます。
あと、この問題を追及してるときに、String オブジェクトに to_u8 ってメソッドが生えててなにこれ、と思ったら、lib/citrus/utils.rb にあると、woremacx さんに教えてもらった。オープンクラスで再定義、なるほどー。
■Citrus で twitter の URL が貼られたときに tweet の内容を表示する plugin
irc.lazy-people.org とかに居る mobitaro のバックエンドは chokan だったんですが、twitter の url が貼られたときに、中身を表示してくれという feedback があって、せっかくだからと Citrus に移行した。
だいぶ if 文まみれだけど、とりあえずは動くということで。
■iQuestioner がアップデートされました!
忙しくしているうちにすこし間が開いてしまいましたが、皆様いかがお過ごしでしょうか。
最近仕事で関わってた iPhone アプリで iQuestioner という、タッチする度にランダムに問いかけを投げてくれるアプリがあるんですが、今日 twitter 機能を搭載してアップデートされました!
質問に対して答えると #iQuestioner に投稿される仕組みです。
そこで、通勤時間を利用して #iQuestioner にボットを投入しました。

iQuestioner に時折現れる、悩み多き「彼」と思わず一言いってしまう「犬」です。
一カ国語につき約60個の台詞 x 日英中の三カ国語で180個 + 自分が勝手に付け足した台詞がいくつかをランダムに1日2回くらい掛け合います。
そしてソースはこんな感じ。ruby 1.9 対策を入れたけど動かしてるサーバは 1.8 系なので意味ないです。
ネームスペース考えて区切ってたつもりが途中からこんがらがってますね >_<
Lazy さんにつけてた自動フォロー返しも搭載してるので、フォローしてね! (そして放置してる Lazy さんごめんなさい >_<)
#iQuestioner で他の人の答えとか見る際に、ちょっとした楽しみになっていただければ幸いです!
ちなみに @iQuestioner はボットじゃないです。中の人は僕でもないです。
あと iQuertioner の回答機能は twitter のアカウントを持ってない人でもローカルに自分の返事を保存しておけるので、以前見た質問がまた出たときは、是非「自分は前にどう答えたんだっけ?」と振り返りに使えますよ!
■クラス名と名前空間かぶるとダメ?
Foo::Bar というクラスのクラスメソッドを Fuga::Foo のメソッドの中で使おうとしたら、Fuga::Foo::Bar なんてクラス無いよと怒られたのでメモ。
追記
IRC で lyokato さんが答えを教えてくれました。
lyokato: ::Foo::Barにしたら呼べるよ!
module Fuga
class Foo
def hogera()
p ::Foo::Bar.test # 頭に :: をつける
'Fuga::Foo.hogera'
end
end
end
foo = Fuga::Foo.new
p foo.hogera
これで上手く行きました。
実行結果
"Foo::Bar.test" "Fuga::Foo.hogera"
どうも呼び出したコンテキストの階層から探しに行って、Fuga::Foo に Foo がマッチしちゃうらしい。頭に :: つけるとトップレベルとして認識されるのね。
元の疑問
環境
- Mac OS X 10.5.8
- ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-darwin9]
test というクラスメソッドを持った、Foo::Bar と言うクラスを作ります。
module Foo
class Bar
def self.test()
'Foo::Bar.test'
end
end
end
Foo::Bar を Fuga::Foo の hogera で使おうとします。
module Fuga
class Foo
def hogera()
p Foo::Bar.test
'Fuga::Foo.hogera'
end
end
end
foo = Fuga::Foo.new
p foo.hogera
すると NameError が >_<
hoge.rb:12:in `hogera': uninitialized constant Fuga::Foo::Bar (NameError)
from hoge.rb:19:in `'
でも、クラス名を変えてあげると大丈夫。
module Fuga
class Awawa
def hogera()
p Foo::Bar.test
'Fuga::Awawa.hogera'
end
end
end
awawa = Fuga::Awawa.new
p awawa.hogera
実行結果
"Foo::Bar.test" "Fuga::Awawa.hogera"
なんでだろ。まだ、よくわかってないですね。
あと、やたら名前空間区切りたくなるんだけど、おかしいのかも。作ろうとしてるの、module じゃないからなぁ。
■IRC と twitter の橋渡しをする lazy さんを作りました
lazy people のマスコット、lazy さんの twitter ボットを作りました。今後はイベントごとがあるときはこっちにも通知していこうと思います。
また、twitter で連絡したい人は @lazy_san にもリプライすると良いと思いますよ。
(@lazysan は関係ない人ですw)
@lazy_san に reply すると irc.lazy-people.org 上の #project にいる irc bot, lazy_san が IRC 内に通知してくれます。
また、IRC 上の lazy_san に話しかけると twitter 上の @lazy_san が発言します。
09:25 d**y: lazy_san: オーハーヨーーーウィ 09:25 lazy_san: d**y: lazy_san: オーハーヨーーーウィ

あとはフォローしてくれたら自動でフォロー返します。お気軽にフォローオ願いします。
ソースはここ。前回の thanksbot と同じディレクトリにいます。
前回書いた thanksbot にもフックするためにまた ruby で書きました。というか、ruby の練習台ですw
あー、thanksbot のプロセス殺して lazy_san 側で呼びかけられ方で振り分けても良いなぁ。でも nick 一覧にないと補完されなくて面倒か。
個人的には thread に触れたことがないので、こんなんで良いのかどうか気になります。
#!/usr/bin/env ruby
# encoding: utf-8
$LOAD_PATH << "lib"
require 'rubygems'
require 'net/irc'
require 'observer'
require 'lazysan'
require 'yaml'
class LazySan::IRC < Net::IRC::Client
def initialize(config)
@channel = config[:irc][:opts][:channel]
@lazysan = LazySan::Twitter.new(config[:twitter][:user], config[:twitter][:pass])
super(
config[:irc][:host],
config[:irc][:port],
config[:irc][:opts]
)
end
def on_rpl_welcome(m)
post JOIN, @channel
run_observe_twitter()
end
def run_observe_twitter()
@message_thread = Thread.new do
loop do
begin
@lazysan.auto_follow
@lazysan.replies.each {|status|
post NOTICE, @channel, "@#{status['user']['screen_name']}: #{status['text']}"
}
rescue
# TODO: Net::IRC の log
end
sleep 300
end
end
end
def on_privmsg(m)
if match = m[1].match(/^lazy_san:\s*(.*)/)
begin
@lazysan.update(match[1])
post NOTICE, @channel, "#{m.prefix.nick}: #{match[0]}"
rescue
post NOTICE, @channel, "投稿ミスった >_<"
end
end
end
end
config = YAML.load_file('lazysan.yaml')
lazy_san = LazySan::IRC.new(config)
lazy_san.start
クラス構成が LazySan::IRC と LazySan::Twitter とあって、LazySan::IRC が LazySan::Twitter に依存してるのも少し変な気がする。
オライリージャパン
売り上げランキング: 33589

最も信頼できるRubyの本
基本書にふさわしい本
rubyマスターになるために
鬱にされる鬱然たるRuby教科書
For Rubist■irc.lazy-people.org#project に thanksbot を復帰させました。
少し間が開いてしまいましたが、irc.lazy-people.org#project にありがとうを伝える thanksbot を放流しました。
この bot に対してありがとうを伝えると http://lazy-people.org/#ありがとう新着順 の一覧に載ります。まぁ、単純なボットですね。
このチャンネルには元々 thanksbot がいたのですが、lazy-people.org Xen 化作戦失敗以降復帰させていなかったのでした。
旧 thanksbot は mojunc という tomyhero 製 Web API を使っていたのですが、これを復帰させるのがめんどうだったので Wedata を使うことにしました。サーセン >_<
Wedata の使い方はこれで良いのかも謎w
そして、せっかくだからと覚え立ての ruby を使って書くことにしました。
IRC の bot 化には Net::IRC::Client を使い、Wedata への投稿には、こちらのモジュールを使わせていただきました。オリジナルの wedata.rb は、JsonParser に依存していたのですが、gem でインストールできる JSON を使うように少し修正しています。(修正したコード)
新規追加しかしないから wedata.rb は大げさだったかも。
#!/usr/bin/env ruby
# encoding: utf-8
$LOAD_PATH << "lib"
require 'rubygems'
require 'net/irc'
require 'wedata'
require 'observer'
require 'yaml'
require 'pp'
thanks_config = YAML.load_file('config.yaml')
class ThanksBot < Net::IRC::Client
include Observable
def initialize(*args)
p args
@channel = args[2]
args.delete_at 2
super
end
def on_rpl_welcome(m)
post JOIN, @channel
end
def on_privmsg(m)
if match = m[1].match(/^thanksbot:\s*(.*)/)
changed
notify_observers('', match[0])
post NOTICE, m[0], "#{m.prefix.nick}: #{match[0]}"
end
end
end
class ThanksDB < WedataDatabase
def update(name, message)
create_item(name, { 'message' => message })
end
end
thanksbot = ThanksBot.new(thanks_config['irc']['host'], thanks_config['irc']['port'], thanks_config['irc']['channel'],thanks_config['irc']['nicks'])
thanksdb = ThanksDB.new('thanks', thanks_config['wedata_api'])
thanksbot.add_observer(thanksdb)
thanksbot.start
ソースはここにあります。
Net::IRC::Client を継承した ThankBot と WedataDatabase を継承した ThanksDB は ovserver ライブラリを使って observer パターンで動作をひもづけてます。まつもとゆきひろ コードの世界を読んでいて、これを試して見たかったというのが大きいかもw
たぶんなにげに初めて書いた ruby プログラムのような気がします。
既存のライブラリを組み合わせただけでお手軽でした。ありがとうありがとう!
オライリージャパン
売り上げランキング: 13443

基本書にふさわしい本
rubyマスターになるために
鬱にされる鬱然たるRuby教科書
For Rubist日経BP出版センター
売り上げランキング: 40925

Rubyに導入された思考法






