退職しました

私事ですが、7月末日をもって退職いたしましたので、ここにご報告いたします。
先ほど送別会から帰宅いたしました。

あんた誰?

「株式会社○○を退職しました」という記事を見る度に思うこと
しがない WEB†DB エンジニアです。
(技評さんとは何の関係もありませんし、記事を書いたこともありません。毎号読んではいます)

やめた会社

Web システム開発受託やホスティングをやっている従業員数3〜5人くらいの小さい会社です。
私が大学4年の3月に就活を始めて、なんとか内定をもらった2つの会社のうちの1つでした。

学んだこと

Perl とか Java を使って WEB システムを作るにあたっての一通りの事は学べたと思います。(まだまだ至らぬ所が多いですが)
中でも SQL の扱いなどは割と慣れたもんで、生でゴリゴリ書いたり、ORM に書かせたり(書いてもらうのではなく)はつつがなく出来る感じになりました。
技術的な事の他にも、提案から保守まで一貫して引き受けるスタイルの仕事でしたので、お客さんとの折衝も含めて幅広く学べたと思います。

困っていたこと

他の従業員が出社したりしなかったり、暗くなってから出社してくるのがキツかったです。
「プログラマは時間に縛られない(キリッ」と言われても、お客さんとのやり取りも我々の仕事なのですよ?
結局、お客さんの稼働時間帯との兼ね合いで、問い合わせ対応や各種事務などの作業は私1人に集中しがちになっていました。
また、横の繋がりが希薄になり、各プロジェクトの属人化が進んでいました。これは問い合わせ対応時に相当な負担となっていました。

零細における受託開発の限界

今のままのビジネスモデルで会社や社員が富やパワーを蓄えることが出来るのか、疑問に思っていました。
受託開発で利益を増やしたかったら、大雑把に言って人月単価を上げるか稼働率を上げるかしかないと思います。単価を上げると言っても、人月単価の相場(60万〜120万/人/月くらいですかね)ってのがあるみたいで、それを逸脱すると結構強く突っ込まれたりしますので、額面を上げていくのは難しいと思います。
では稼働率はどうかというと、すべての従業員が毎月1人月ずつ消化する状態は保てていましたので、稼働率をこれ以上に上げるということは、稼働率を120%、150%、200%としていく事に他なりません。ところが、小さい会社ですので、”本当の”受注情報をみんなが知っています。例えば「納期」「受注額」「人月数」などです。それらを知っていると、仕事のクオリティが、そこに合っていきます。もっと短期間で出来るはずの事が「本当の納期」に引きずられて「見積もり通りの人月」に収まったり、酷いときには納期に遅れたりします。「この仕事、とっくに終わってるけど、提出期限までまだまだ期間があるから出さんとこ」みたいな事も横行します。
早くできるものを早くやる事による圧縮は相対的に単価を上げることになるんですが、エンジニアに見返りが無ければ全体に還元されないようです。「レバレッジを効かせてみんなで豊かになろう」ってコンセプトを経営層も含めて共有できない限り、人月が見えちゃってるエンジニアの生産性は上がりにくいのかなと思います。(単にうちの意識が低いだけだったのかもしれませんが)

なぜやめたのか

受託開発には、お客さんの求めるサービスを見出し、それを形にしたモノがお客さんの求めるモノであったときに感じられる喜びがあります。ただ、やはりどこか他人事な感じが常につきまとい「契約内容さえ満たせてればおっけーだし」と思ってしまう癖がついていました。そういう自分を客観的に見て、このままでは誰も幸せにならないという想いを抱いていました。それが今回の辞職の原動力となっています。

どこかで「自社サービスのエンジニアは24時間365日、自社サービスについて考えている」というようなことを聞きました。これを聞いてからずっと頭の中でリフレインしており、意識していました。そして、もし転職するなら自社サービスをやっている会社のエンジニアになろうと決意していました。

あと、仕事で思う存分 Ruby を使いたかったんですが、既存の案件を急に Ruby にするわけにもいかず、悶々としていました。

次の職場

とある広告代理店に就職しました。
この会社はB2Bの自社サービスを運営しており、今までは開発運用は外注していました。
そこへ内製への舵取りをしたらどうかと提案したところ実現し、そこに生まれたポストに私が収まった形です。
今までにエンジニアを雇ったことが全く無い会社だったので、エンジニアのポストを作るところから交渉して内定をもらいました。

これからの仕事

当面はサービス周りの色々な事象を見える化したり、自動化したりする作業が続くと思います。
Ruby を使う事ができる場面がかなり増えそうなので、非常に楽しみです。
24時間365日、このサービスの事を考え、手を動かし、価値を創造していきます。

まとめ

エンジニアの居ない場所に行ってポストを作れさえすれば、割と無双できます。
そこで、井の中の蛙になって腐らない限り、みんな幸せになれそうです。
今『Team Geek』を読んでいますが、この状況に役立つ事が色々書いてあるげです。さらに熟読しようと思います。

後日談

1年前に転職しました

2年前に転職しました

カテゴリー: 未分類 | 7件のコメント

rubyhiroba で、すとうさんから学んだ事(前編)

※ 注意
※ このエントリはほぼ実話ですが、細部については記憶の欠落や脚色があります。
※ 予めご了承の程、よろしくお願い致します。

ruby hiroba に参加してきたので、レポートを一人称の小説風に書いてみます。

わしは druby hiroba が終わった後、景色のいいテーブル席でもくもくと復習していた。そこに、Ruby コミッタのすとうさんが、意識の高そうな rubyist を3名ほど引き連れてやってきた。

すとうさんは空席を指差して「ここいいですか?」
わし「はい、もちろんどうぞ」

そうして着席した彼らの話を聞いていると、なにやら、これからリーダブルなコードを崇めるサバトを開くとのこと。なにそれ怖いと思いながら、もくもくに戻ろうとするわしに…

すとうさん「当然、あなたも参加されますよね?」
わし「え!?あ、はい。よろしくお願いします」

ですよね。そこにいるんだから参加ですよね。

すとうさん「以前『リーダブルコード』が出版されたときにワークショップをやったんです」
わし(DevLOVE 2012 の『リーダブルコードを読んだ後』のことかな。わしも参加してたわ)
すとうさん「そこでは講師の立場だったのですが、むしろ自分で参加したいと思って、この場を設けました」
すとうさん「まず、なんでもいいので、既存のソースコードを読んでいきましょう」
すとうさん「そこで、リーダブルな所、アンリーダブルな所を見つけたら、その理由を挙げていきましょう」

なるほど、RubyKaigi での発表の実践というわけですね。コードのリーダブルな良い所が見つけられれば、それを真似できるので、自分のコードに生かせますね。

すとうさん「では、みなさんの中で、この場の題材にするコードをお持ちの方は?」
みんな「あー。仕事で書いてるコードは公開できないし、あんましないですねー」
すとうさん「そうですか。みなさんは普段『公開できないコード』をお書きになってるんですねぇ(震え声)」

そう言えば、すとうさんは、ぐんま Ruby 会議での招待講演の際にも「私はフリーソフトウェアプログラマー」と、熱く語っていた。プロプライエタリなソフトウェアについては色々と思うところがあるのかもしれない。

すとうさん「では、何かライブラリのソースでも読みますか。最近使ったライブラリ、何かありますか?」
わし「Rabbit ですね」

後に、この発言をする前にセーブしておかなかった事を後悔するとは、わしには知るよしもなかった…
(つづく)

カテゴリー: イベント | 1件のコメント

ぐんまRuby会議へ行ってきました

ぐんまRuby会議01へ行ってきました。

出発

午前中は家の用事などがあり、時間の余裕が無かったので、新幹線で行きました。
人生初の2階建て新幹線『E4系 Maxたにがわ』に乗りました。2階の窓から外を眺めていると、すれ違う『こまち』や『はやぶさ』のパンタグラフが丸見えで面白かったです。「パンタ丸見えアングル」です。

E4系Maxたにがわ

旅路

高崎駅から会場までは2kmくらいあったのですが、せっかく初めて降り立つ地なので歩いて向かいました。
途中、踏切があったのでカメラを構えていたら、湘南色の上越線が来たので撮影しました。帰宅後に息子に見せたら好評でした。

湘南色の高崎線

基調講演

最初は『初めてのRuby』の著者 yugui さんの基調講演でした。
家に IA-64, MIPS, RISC, Power その他多数のアーキテクチャのマシンを揃えて、それぞれのマシンで Ruby をビルドしているそうです。
「Ruby は今は WEB を主戦場にしているが、今後、様々な分野で活躍すると思われる。その時に備えて、いろいろな環境で動かせるように確認しておく必要があるのだ」とおっしゃっていましたが、正直それは建前で、変態なだけなんじゃないかなと思いました。でも、最後まで話を聞いてみると、決して変態だけではないという事が分かりました。本気で理想の世界を目指して取り組んでいらっしゃるようでした。(参考:ぐんまRuby会議01で発表した

様々なアーキテクチャでRubyをビルドするというyuguiさん

招待講演1 「プログラマー」 須藤功平さん

「プログラミングでつまづく人を少なくしたい。ではそのためにはどうすべきか」
「問題を”回避”しないこと。バッドノウハウをドキュメントに書いて回避するなどしていると、やはりつまづく人は絶えない」
「根本的な原因を直す事が大事」
「そのためにはソースコードがなければならない」
「そこでフリーソフトウェアですよ」
あえて OSS と言わずにフリーソフトウェアとおっしゃっていたのは、自由ソフトウェアの哲学からなのでしょうか。
質疑応答での咳さんとの絡みが面白かったです。Ruby コードの感想戦 【第 2 回】 WikiRの続きを読んでいるかのようで、須藤さんと咳さんの仲の良さが伝わってきました。

招待講演2 「サラリーマン」 大場光一郎さん

ロールプレイングゲームの内容を軸に、サラリーマンプログラマーとしてどのように生きてきたかというお話でした。
「就職先はコードが書ければどこでも….良くない!」

群馬の中心で愛を叫んだけもの

群馬でフリーランスエンジニアをやっている方2人のお話。
発注元の割合が「地元2:東京8」くらいで、リアルで東京に行かなければならないときに大変とのことでした。

LT

「アーティスト」関 将俊さん

「一度それを見ちゃったら、その後はそれを使うしか考えられないような、かつ、普通は思いつかないようなモンがカッコイイ。そういうのを作って見せびらかすためのものが、オレにとってのオープンソースだZE」って感じでカッコ良かったです。

「自由ソフトウェア GnuPG と Gnuk Token」g新部 裕さん

「お前ら、オープンソースって言うな!自由ソフトウェアだ!覚えとけ!」って感じで怖かったけど、カッコ良かったです。

「みんなで使おう!愉快に書けるWebアプリケーションフレームワーク Padrino」こしば としあき(@bash0C7)さん

Padrino Blog Tutorialを見れば簡単に使い始められるので、みんな使いましょう!ついでに、開発にも参加しちゃいましょう!」というアピールでした。

「群馬vs東京」五十嵐邦明(@igaiga555)さん

「群馬と東京は人口が17倍も違う。勉強会をやろうにも、東京で50人集まるようなものでも、群馬だと3人だったりするのがキツい。東京はイベントが成立するための閾値が低い。そういう東京に、経験値稼ぎのためにやってきた」確かに、よほどニッチなテーマでも、数名は集まりそうですね。東京。密度は世界トップレベルでしょうし、ヘタしたら世界で一番、勉強会を開きやすい都市なのかもしれません。

「Ruby本から読み解くRuby考古学」斎藤ただしさん

オブジェクト指向スクリプト言語 Ruby (ASCII SOFTWARE SCIENCE Language)』が出版されるまでのいきさつなどを語って下さいました。「俺たちは Matz の夢の中で生きてるんだ!」熱かったです。

「Rubyが私にくれたもの」寺嶋章子(@shokolateday)さん

「プログラムは思うように動かない、書いたように動く。という論理的な考え方は子育てにも生かされている。現在、Rails で保育園SNSを作ってます」保育園SNS、期待しています。休憩時間に2人のお子さんが乱入して来ましたが、大変可愛かったです。

ゆRuby Beyond

guRuby の方々は普段『初めてのRuby』を写経されているそうです。
このセッションでは著者の yugui さんを交えて、会場全員で写経を行いました。
対象は「9.6 Rubyの黒魔術」です。
当日、質疑応答で yugui さんのコメントが色々あったので、拾えた範囲でソースのコメントに書きました。

9.6.1 eval 族

# -*- coding: utf-8 -*-
# 文字列評価
b = binding
# 読者に binding とは何か?と思わせるために、b=binding を入れた
while code = gets
  p eval(code, b)
end
# -*- coding: utf-8 -*-
# コンテキストのすり替え
class CybernetedAndroid
  def initialize(name) @name = name end
end

proc = Proc.new {
  p self
  p @name
}

proc.call

dicey = CybernetedAndroid.new("dicey1")
dicey.instance_eval(&proc)

dicey = CybernetedAndroid.new("dicey2")
CybernetedAndroid.class_eval do
  def save; puts "saved" end
end
# do .. end と { } について
# 返値を代入したい時には { } にしている 
dicey.save

なんか「手元に tk が入ってないー!」とかって声があちこちから聞こえたんですが、みなさん Ruby1.8 を使ってるんですかね?

# -*- coding: utf-8 -*-
# 言語内 DSL
require 'tk'
TkLabel.new {
  text "Hello, World"
  bg "red"
  pack
}
TkButton.new {
  text "Close"
  command {exit}
  pack
}
Tk.mainloop

9.6.2 method missing

# -*- coding: utf-8 -*-
class Reporter
  def method_missing(method_name, *arguments)
    puts "メソッド #{method_name} が次の引数で呼ばれました"
    arguments.each{|arg| puts arg}
  end
end
reporter = Reporter.new
reporter.report
reporter.emargency 1,2

9.6.3 set_trace_func

これ、pry で実行したら大変な事になりましたw

# -*- coding: utf-8 -*-
# 最後に頼りになるのは debugger
set_trace_func proc {|event, file, line, id, binding, classname|
  printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
1 + 1

9.6.4 継続

# -*- coding: utf-8 -*-
require 'continuation' if RUBY_VERSION >= '1.9'
1.upto(10) do |i|
  if i == 3
    $cont = callcc{|continuation|
      continuation
    }
  end
  print i, ' '
end
$cont.call(nil) if $cont
# call の引数に nil を入れるのはなぜ?
# callcc の返値になるので、無限ループしなくなるという仕組み
# callcc の cc とは current continuation の事
# 『プログラミング言語 SCHEME』を参照

質疑応答

Q: 他の黒魔術は?
A:この章には書いてないけど、ruby の黒魔術について語るなら、send メソッドの存在を忘れてはならぬぞよ

Q:『初めての Ruby』の次に取り組むべき本は
A: リファレンスマニュアルでも読んだらいいんじゃないですかね。もしくは幸福の王子本
※幸福の王子本というのはdRubyによる分散・Webプログラミングの事ですかね

カテゴリー: イベント | コメントする

26個目のアンチパターンについて『SQL アンチパターン』

SQLアンチパターンを発売日に買って、それなりに熱心に読みました。
これはどえらい本が出てきたなってことで、理解を深めるため、関連する3つのイベントに片っ端から参加しました。

一つ目は DevSumi のセッション
SQL アンチパターン – 開発者を待ち受ける25の落とし穴( 2/15 )

二つ目はジュンク堂のトークセッション
データベースを巡る世代間闘争( 2/21 )

三つ目は DevLove #110
SQL アンチパターン・レトロスペクティブ -データベース危篤患者の救出-( 2/26 )

三つめのイベントで「みなさんも26個目のアンチパターンを考えてみて下さいね」という趣向があったので、わしも一つ提案してみようと思います。

26個目のアンチパターン

名前

オーバードライ(やりすぎDRY)

目的

重複する定義の排除

アンチパターン

<例1>
「amount が色んなテーブルに定義してあるのは冗長なので、amounts テーブルを作って、各テーブルには外部キーとして amount_id を持たせましょう。amount 属性の値を入れたい時は、まず select id from amounts して、見つかったらその id を外部キーにします。見つからなかったら insert します。その後、改めて select すれば、id が得られるはずなので、それを外部キーにします」
というような事をしてしまうと、
「こっちのクラスで想定している amount は 1000 未満に制限したいんですが!」
「でも、こっちのクラスの amount は 1000 の倍数じゃないとダメです!」
「矛盾してる\(^o^)/ 」
という事態になりかねません。

<例2>
「住所と名の付く属性は addresses テーブルへまとめて、必要なテーブルから参照しましょう。addresses テーブルの属性は、住所を必要とするテーブルのニーズを全部カバーしましょう」
というような事をしていると、
「こっちのクラスの住所には郵便番号が必須ですよ」
「でも、こっちのクラスからは郵便番号が入力出来る保証が無いので NOT NULL 付けるのはやめてください」
「矛盾してる\(^o^)/ 」
という事もしばしば。

アンチパターンの見つけ方

「とにかく、同じ名前の属性が無いかどうか、徹底的にチェックしよう」
という号令で、機械的にまとめていると、事故が起こりやすい気がします。

アンチパターンを用いても良い場合

当該属性が、ドメイン的に同一の概念である事が考慮されている場合には、何とか使えなくも無い気がします。ただ、数量のようなものまで共通化してしまうと、check 制約などを付けたいときなどに困るでしょうし、何より、使いにくいです。

解決策

共通のテーブルを定義するにあたって、文脈によって必須であったりそうでなかったりする属性については、用途に応じて特化したサブテーブルを作る事によって対応するといいでしょう。例えば、郵便番号が必須なクラスが必要としていた「住所」というのは、実は「配送先」であったというような事です。サブクラスとして「配送先」を作れば、矛盾を避けることが出来ます。
『「分ける」ことは「わかる」こと』と言われることがあります。ドメインの分析をきちんと行って、同じものは同じに、違うものは別に、という分別をする必要があるという事でしょう。

感想

私のいたグループで、この話をしていたところ、和田省二先生がいらっしゃり、「住所テーブルの話ですか?本来、住所ってのは、緯度経度ですよ!」という話をされはじめて、どひゃあ!ってなりました。その後、「サブテーブルを作って余計な属性を追い出す」という本件の解決策について、教えて頂きました。ありがとうございました。

27個目のアンチパターン

名前

シックスセンス(第6正規形)

アンチパターン

こちらは名前のみの出オチで、アンチパターンと言うと語弊がありますが、付録 A.3.7 に「Bugs テーブルが完全に第6正規形をサポートするには、ほぼ全ての列に個別の履歴テーブルが必要になり、テーブル数が過剰に増えてしまいます。第6正規形は、ほとんどのアプリケーションにとって過剰な正規形です。ただし、データウェアハウスの一部では、第6正規形が使用されています」と書いてありましたね。
HBase なんかでも素でカラム毎の履歴保存をやってくれたりするみたいなので、本当に履歴にこだわるならそういうモノを使う事も検討に値するでしょう。

カテゴリー: イベント | コメントする

[技術書つまみ食い] 『MongoDB イン・アクション』第五回

[技術書つまみ食い] 『MongoDB イン・アクション』第四回 の続きです。

4章 ドキュメント指向データ

写経コード管理用 git

とりあえず立てたので、じゃんじゃん突っ込んでいくことにします。
yancya/mongodb_in_action

キャップ付きコレクション

require 'mongo'

VIEW_PRODUCT=0
ADD_TO_CART =1
CHECKOUT    =2
PURCHASE    =3

@con = Mongo::Connection.new
@db  = @con['garden']

@db.drop_collection("user.actions")
@db.create_collection("user.actions", capped: true, size: 1024)

@actions = @db['user.actions']
40.times do |n|
  doc = {
    username: "kbanker",
    action_code: rand(4),
    time: Time.now.utc,
    n: n
  }

  @actions.insert(doc)
end

12行目で size: 1024 と指定する事で、このコレクションの最大サイズを 1024 バイトに制限しています。
この制限サイズを超えると、古いレコードから順に消去されていく仕組みです。

とりあえずまとめ

とりあえずキャップ付きコレクションの動作だけ確認したけれども、本当にフローなデータを取り扱うことに集中した機能だなと思う。
トランザクションとかロールバックってどうするのか気になる。きっとこの先に書いてあるよね。
4章は残りわずかだけど、眠いので今日は以上!

カテゴリー: 未分類 | 2件のコメント

[技術書つまみ食い] 『Emacs 実践入門』第一回

この本は一体?

Emacs24 に対応した比較的新しい本。ざっと写経しながら動作を見ていきました。

写経結果

こういう設定ファイルになりました。

今のini.el

とりあえずまとめ

去年まで、わりとカオスな設定だったけど、色んな elisp を package の奴に入れ替えたりとかしてスッキリしたかも。
やっと elisp にも慣れて来たので、もうちょい複雑な関数を自分で書いてみたい。

カテゴリー: 技術書つまみ食い | コメントする

[技術書つまみ食い] 『MongoDB イン・アクション』第四回

[技術書つまみ食い] 『MongoDB イン・アクション』第三回 の続きです。

3章 MongoDB を使ったプログラムの作成

前回は TwitterAPI の検索結果を MongoDB へ格納するところまでをやりました。
今回は格納されているデータを使って Web 画面に Tweet の内容を表示させます。

ハマったので fix

まぁ、ハマったって程では無いですが、やっぱり TwitterAPI の最新の仕様への対応は必要ですね。erb の一部に修正が必要でした。
当該箇所(p63)のサンプルコードは下記の通り。

  <body>
    <h1>Tweet Archive</h1>
    <% TAGS.each do |tag|%>
      <a href="/?tag=<%= tag %>"><%= tag %></a>
    <% end %>
    <% @tweets.each do |tweet| %>
      <h2><%= tweet['text']  %></h2>
      <p>
        <a href="http://twitter.com/<%= tweet['from_user'] %>">
          <%= tweet['from_user'] %>
        </a> on <%= tweet['created_at'] %>
      </p>
      <img src="<%= tweet['profile_image_url'] %>" width="48" />
    <% end %>
  </body>

現行の TwitterAPI のレスポンスには from_user とかが無いので、実際に格納されているデータの構造を javascript シェルで覗いて、対応するように修正しました。
修正版は下記の通り。

  <body>
    <h1>Tweet Archive</h1>
    <% TAGS.each do |tag|%>
      <a href="/?tag=<%= tag %>"><%= tag %></a>
    <% end %>
    <% @tweets.each do |tweet| %>
      <h2><%= tweet['text']  %></h2>
      <p>
#       <a href="http://twitter.com/<%= tweet['from_user'] %>">
        <a href="http://twitter.com/<%= tweet['user']['screen_name'] %>">
#         <%= tweet['from_user'] %>
          <%= tweet['user']['screen_name'] %>
        </a> on <%= tweet['created_at'] %>
      </p>
#     <img src="<%= tweet['profile_image_url'] %>" width="48" />
      <img src="<%= tweet['user']['profile_image_url'] %>" width="48" />
    <% end %>
  </body>

動作結果

sinatra サーバーを立ち上げてアクセスしたら、ちゃんと動いている事が確認できました。
twitter_archive

とりあえずまとめ

Twitter みたいに、レスポンスのデータ構造がコロコロ変わるようなサービスと接続するアプリケーションを作るにあたって「とりあえずレスポンスを丸々保存しておいて、使うときに調整する」みたいなアプローチは超強力と言わざるを得ないですね。スキーマレスって、アタマでは理解していたつもりだったけど、思っていた以上に楽だって事が分かりました。
ココまでで第1部がおしまい。次から第2部4章です。これまでとは違って、少し複雑なアプリケーションを作るようなので、書いたソースは随時 github にプッシュしながら進めていこうかと思います。
以上!

カテゴリー: 技術書つまみ食い | 1件のコメント

[技術書つまみ食い] 『MongoDB イン・アクション』第三回

[技術書つまみ食い] 『MongoDB イン・アクション』第二回 の続きです。

3章 MongoDB を使ったプログラムの作成

この章は、The Twitter Ruby Gem を使って Twitter の検索結果を取得して MongoDB へ突っ込んでいくというサンプルです。

ハマったので fix

写経なので、一言一句間違いなくソースをタイプして動かしたんですが、動きませんでした。( uninitialized constant Twitter::Search (NameError) )
gem i twitter したあと、require ‘twitter’ して下記のコードを動かすっていう部分です。(p59)

  def save_tweets_for(term)
    Twitter::Search.new.containing(term).each do |tweet|
      @tweets_found += 1
      tweet_with_tag = tweet.to_hash.merge!({tags: [term]})
      @tweets.save(tweet_with_tag)
    end
  end

わしが動かした時点の The Twitter Ruby Gem のバージョンは 4.4.2 ですが、Twitter:Search は既に存在していませんでした。
Twitter API への get だけであっても、認証済みクライアントを使うことが推奨(もしくは強制?)されている影響っぽいっすね。
下記の様に、まず Twitter::Client のインスタンスを作って、search メソッドで検索すれば結果が出てきます。※ ***** の部分は適宜用意したものをセット

  def save_tweets_for(term)
    client = Twitter::Client.new(
      consumer_key: "*****",
      consumer_secret: "*****",
      oauth_token: "*****",
      oauth_token_secret: "*****"
    )
#   Twitter::Search.new.containing(term).each do |tweet|
    client.search(term).results.each do |tweet|
      @tweets_found += 1
      tweet_with_tag = tweet.to_hash.merge!({tags: [term]})
      @tweets.save(tweet_with_tag)
    end
  end

とりあえず動く事が確認できたから、次回は initialize で @client を作って使い回すように修正してから続きをやりましょう。

とりあえずまとめ

写経してるとこういう事もあるよね!
次回は、収集した tweets を sinatra で表示するところをやります。
以上!

カテゴリー: 技術書つまみ食い | 1件のコメント

[技術書つまみ食い] 『MongoDB イン・アクション』第二回

[技術書つまみ食い] 『MongoDB イン・アクション』第一回 の続きです。

2章 JavaScript シェルから使う MongoDB

環境

こっからハンズオンでガリガリやっていくわけですが、わしの環境を紹介しておきます。
OS: MacOS X 10.8.2
MongoDB: v2.2.2
こんだけ。MongoDBv2.2.2 を落としてきて、解凍して起動しただけです。

cd mongodb-osx-x86_64-2.2.2/bin
./mongod --dbpath=/Users/yancya/data/db/

CRUD 操作

いわゆる CRUD 操作をガリガリやっていきます。
シェルの起動は簡単

./mongo

だけ!
次にデータベースへの接続。tutorial という名前のデータベースへ接続します。
そんなデータベース作った覚えがない?問題ない!無くても繋がるw 実体は最初に insert するときに勝手に作られる。

> use tutorial

[Create]

> db.users.insert({username: "yancya"})

[Read] 挿入したレコードに _id という名前でハッシュが付与されているのが分かります。これがプライマリキーです。

> db.users.find()
> db.users.find({username: "yancya"})
> #=> { "_id" : ObjectId("50e5a5cf87d9241065406c71"), "username" : "yancya" }

[Update] 条件と更新内容を喰わせます。単なる set 意外にも unset とかイロイロあります。

> db.users.update({username: "yancya"}, {$set: {city: "adachi-ku"}})

[Delete] 条件がなければ全件消去します。

> db.users.remove({username: "yancya"})

[Create or Update] _id が無ければ insert、あれば update します。

> db.users.save({username: "yancya"})

インデックス

インデックスは昇順(1)降順(ー1)で指定できる。ネストの奥にも指定できたりする。

> db.users.ensureIndex({username: 1})
> db.users.ensureIndex({address.town: -1})

おまけ

insert, find, update, remove, save らは function なので、() を抜いて実行してみると実装が画面に表示されてきて楽しいよ。javascript のソースがそのまんま出てくる。

とりあえずまとめ

わりと簡単に使えて楽しいね!

> db.users.count({"address.town":"aoi"})

とかもある。
適切にインデックスつけていけば、集計とかもガリガリできそうだし、大変興味深いですね。
次回、3章は MongoDB を使ったプログラムの作成です。Ruby のドライバで接続してイロイロやりましょう。20ページくらいだけど、今回カツカツだったので、2回に分けたりするかも。
以上!

カテゴリー: 技術書つまみ食い | 1件のコメント

[技術書つまみ食い] 『MongoDB イン・アクション』第一回

この本は一体?

先日パラっと読んだ『NoSQL データベース ファーストガイド』に出てきた MongoDB について、手取り足取り教えてくれる本です。立ち読みしたら、Ruby と javascript を使って説明していきますって書いてあったので、うひょーって思って買っちゃいました。NoSQL の中でも、わしの手の届く範囲内で一番役に立ちそうなのはドキュメント指向の奴だと感じたので、とりあえず代表的な MongoDB に入門してみて、手応えを感じようという趣旨で読みます。

1章

ドキュメント指向DBとは

ザックリ言うと、ハッシュマップにユニークなID付けて、そのまま保存しちまえっていう発想のDBなのでしょう。非正規化側に振り切った考え方ですね。BSON っていう独自のバイナリ形式で保存するようです。

検索とかどうすんの

単なるハッシュマップの集合を保存していますってだけだと、検索とか集計とか困るんじゃないの?極端な話、ファイルとして積んでおいて grep とか awk でゴリゴリ処理するのと何が違うの?っていう疑問に対してはセカンダリインデックスという考え方で対応するようです。B-tree インデックスなのでDBげです。ココ大事だから7章でガッツリやるぜ。

レプリケーション

レプリカセットって単位を3ノードくらいで組む。1つがマスターあとはセカンダリ。マスター転けたらセカンダリがマスターに昇格、マスターだったノードが戻ってきたらセカンダリとして参加。みたいな事を自動でサクッとやれるっぽいっす。

スケーリング

自動シャーディングにより、複数のノードに自動的にデータを分散配置する仕組みでサーバー増やしまくれるぜいぇーい!

コマンドシェル

いわゆるDBコンソールは javascript ベース!SQL は使わないけど、なじみの言語だろうからいいよね!

ドライバ

だいたいある!

ユーティリティ

dump, restore, export, import は普通にある。sniff(経路監視), stat(ポーリング)なんかもある。

制約とか

ジャーナリングするとはいえ、ベースはオンメモリーだから、メモリー沢山積んでるマシンじゃないと実用的じゃないよ。要するに 64bit OS にしとけってこと。

とりあえずまとめ

大体分かったから、とりあえず CRUD とかさせてくれ。な。2章でそれをやるらしい。16ページくらいしかないから明日やるわ。
以上、「読む+このエントリ書く」まで2ポモドーロ也。寝る!

カテゴリー: 技術書つまみ食い | 1件のコメント