dRuby入門の発表資料

9月 10th, 2009 admin

9/6のCSNagoyaで発表(LT)をやらせてもらいましたので発表資料を公開させて頂きます。
dRubyってのは分散オブジェクトシステムを簡単に構築することができる仕組みのことです。ネットワークの知識がほぼ不要なあたりなど、ぜひdRubyの威力をサンプルを触ったりして試してもらいたいと思います。

dRuby
View more documents from toyoshi.

いかに簡単かというサンプル

オブジェクトを共有する最小のサンプルをここに紹介します。今回は配列オブジェクトをdRubyを使って共有してみます。
server.rb

RUBY:
  1. require 'drb/drb'
  2.  
  3. foo = ["apple","orange","lemon"]
  4. DRb.start_service('druby://localhost:12345',foo)
  5. puts DRb.uri
  6.  
  7. sleep

このスクリプトを起動すると、配列オブジェクトfooを共有したdRubyサーバが立ち上がります。
そこにirbで接続してみます
$ irb -r drb/drb

RUBY:
  1. >irb -r drb/drb
  2. > r = DRbObject.new_with_uri("druby://サーバのアドレス:12345")
  3. > p r[0,3]
  4. ["apple", "orange", "lemon"]
  5. => nil

オブジェクトが取得できていますね。では本当に共有できているか確認してみましょう。
いまのirbにつづけて

RUBY:
  1. > r.push "melon"
  2. => ["apple", "orange", "lemon", "melon"]

と入力します。そしてもう一つクライアントを立ち上げて

RUBY:
  1. >irb -r drb/drb
  2. > r = DRbObject.new_with_uri("druby://localhost:12345")
  3. > p r[0,4]
  4. ["apple", "orange", "lemon", "melon"]
  5. => nil

melonが追加されているので、オブジェクトが共有できていることが確認できました。

まとめ

・dRubyはとても簡単に分散オブジェクトを体験できる
・Rindaというシステムがあってそれがとても面白い(こっちをもっと紹介したかった)

関連サイト

dRuby I like Ruby
dRubyの作者である関さんのサイト。Ruby会議などで何度か発表を聞かせてもらっていますが、ゆるい雰囲気をもった素敵な方です。dRubyよりもERBのほうが有名ですね。ここに書籍の内容がですぎているのが書籍が売れない理由な気も・・・

dRubyによる分散・Webプログラミング
関さんが著者のdRubyの入門書 通常「幸福の王子本」 読みやすくわかりやすいです。

amazonで中古の本を上下巻セット買うときのRuby

8月 8th, 2009 admin

・アマゾンで上下巻セットの本を買いたい
・しかも中古で買いたい
・できれば同じ店から2冊買いたい

という要望がたまにあるのだけど、自分でページを見比べるのが面倒なのでスクリプトを書いた。

使用例

ハイペリオン(上)の中古一覧のページハイペリオン(下)の中古一覧のページを調べてコードに投げる

CODE:
  1. $ ruby comp.rb "http://www.amazon.co.jp/gp/offer-listing/4150113335/ref=dp_olp_used?ie=UTF8&qid=1249721097&sr=8-1&condition=used" "http://www.amazon.co.jp/gp/offer-listing/4150113343/ref=dp_olp_used?ie=UTF8&qid=1249724799&sr=1-2&condition=used"
  2.  
  3. #=>"qsemark"
  4. #=>"まにあコレクション"
  5. #=>"晴耕堂"
  6. #=>"イーブックスパイダー吉野の桜店"

とハイペリオンを上下巻セットで出品しているお店の名前がわかる。

コード

Rubyで書いてあります

RUBY:
  1. require 'rubygems'
  2. require 'hpricot'
  3. require 'open-uri'
  4. require 'kconv'
  5.  
  6. $KCODE = 'u'
  7.  
  8. cmp_url1 = ARGV[0]
  9. cmp_url2 = ARGV[1]
  10. list = []
  11.  
  12. name_xpath = '//div[@class="seller"]/a/b'
  13.  
  14. html = Hpricot(open(cmp_url1).read)
  15. html.search(name_xpath).each do |seller|
  16.   list.push(seller.inner_html.toutf8)
  17. end
  18.  
  19. html = Hpricot(open(cmp_url2).read)
  20. html.search(name_xpath).each do |seller|
  21.   shop_name = seller.inner_html.toutf8
  22.   p shop_name if list.include?(shop_name)
  23. end

まとめ

だれかブックマークレットでつくってほしい

全491回 蟹工船をTwitterで読む with Ruby

7月 15th, 2009 admin

蟹工船

青空文庫(http://www.aozora.gr.jp/)で公開されている蟹工船をTwitterで毎日1段落づつ読めるようにしました。
読書が苦手な人にオススメです

読み方

https://twitter.com/kanikosen
をフォローしてください。毎朝8時ごろ一段落だけPOSTされます。

コード

botのコードはRubyで書きました。gemのtwitterをつかったわけですが、このライブラリはバージョンごとに結構使いかたが違うようなので、ネットでの情報を探すより英語の公式サイトを見るのがよさそうです(コンストラクタの引数が1つになってるとか)

RUBY:
  1. #!/usr/bin/ruby
  2.  
  3. require 'rubygems'
  4. require 'twitter'
  5. $KCODE = 'u'
  6.  
  7. filename = "kanikosen.txt"
  8. log_file = "published.log"
  9.  
  10. #マルチバイト文字列を指定文字数で分割して配列を返す(なんか方法ないのかな?
  11. def div_string(str,num=140)
  12.   packed = Array.new
  13.   while part = str.slice!(/.{#{num}}/)
  14.     packed.push part
  15.   end
  16.  
  17.   packed.push(str) unless str == ""
  18.   return packed
  19. end
  20.  
  21.  
  22. last_line = File.read(log_file).to_i
  23. httpauth = Twitter::HTTPAuth.new('loginid','password');
  24. twit = Twitter::Base.new(httpauth)
  25.  
  26.  
  27. File.open(filename){|fp1|
  28.   while line = fp1.gets
  29.     if fp1.lineno> last_line
  30.       posts = div_string(line,140)
  31.       posts.each do |post|
  32.         p post
  33.         twit.update(post)
  34.       end
  35.  
  36.       if line =~ /。$/
  37.         File.open(log_file,"w"){|fp2|
  38.           fp2.puts fp1.lineno
  39.         }
  40.         exit
  41.       end
  42.     end
  43.   end
  44. }

行末の「。」までをPOSTしているだけです。
*実行には、POSTした行数を記録しておくファイルが必要です

まとめ

計算してみたところ491日後に終るようです。楽しみですね!

参考サイト

図書カード:蟹工船
3700のつぶやきと48万文字を経て、今Twitterで創作小説が読める
Ruby Twitter Gem by John Nunemaker

RubyでHTMLを取得 – 検索エンジンを作ろう

7月 10th, 2009 admin

Rubyでつくる検索エンジン
星澤 隆
毎日コミュニケーションズ
売り上げランキング: 82686

この本を読んだので、僕も自分の検索エンジンを作ってみようと思いました。
しかもせっかくなので本を踏襲しながらもオリジナルで作ってみたいなと思ってしまった(よくある失敗の原因ですね)。

とりあえずdRubyの本を半年ぐらい借りており、持ち主に返したいのでdRubyをクローラーのところに使いたい。

クローラー・スパイダー

RUBY:
  1. require "hpricot"
  2. require "open-uri"
  3. require 'kconv'
  4.  
  5. uri = ARGV[0]
  6.  
  7. class Crowler
  8.   def initialize(uri)
  9.     @uri = uri
  10.     @title = nil
  11.     @description = nil
  12.     @src = nil
  13.   end
  14.  
  15.   def get
  16.     begin
  17.       doc = open(@uri)
  18.       @src = Hpricot(doc.read).toutf8
  19.     rescue => ex
  20.       return
  21.     end
  22.  
  23.     @title = (@src/:title).inner_html
  24.     desc_element = @src.search('meta[@name="description"]').first
  25.     @desc = desc_element ? desc_element["content"] : ""
  26.   end
  27. end
  28.  
  29. Crowler.new(uri).get

まとめ

面倒なところは飛ばしてとりあえず、小さいのを完成させよう

rubyのexerbにD&DでFTPアップロード

4月 21st, 2009 admin

exerbを使ってファイルをドラッグアンドドロップしたらあらかじめ指定したディレクトリにFTPでアップロードするスクリプト。

コード

put.rb

RUBY:
  1. require 'yaml'
  2. require 'net/ftp'
  3.  
  4. config = "config.yaml"
  5. if defined? ExerbRuntime
  6.   config = File.expand_path(config, File.dirname(ExerbRuntime.filepath))
  7. end
  8. config = YAML.load(File.read(config))
  9.  
  10.  
  11. ftp = Net::FTP.new(config['host'],config['user'],config['passwd'])
  12. ftp.binary = true
  13. ftp.chdir(config['dir_name'])
  14. ftp.passive = true if config['passive'] == 1
  15.  
  16. ARGV.each do |filename|
  17.   begin
  18.     ftp.put(filename,File.basename(filename))
  19.   rescue => e
  20.     puts "ERROR: #{e}skip #{filename}"
  21.   end
  22. end

config.yaml

CODE:
  1. host: example.com
  2. user: xxxx
  3. passwd: yyyy
  4. passive: 1
  5. dir_name: /aaa/bbb

exerbの使い方

exerbをインストールしたら

CODE:
  1. #レシピファイルの作成
  2. >ruby -r exerb/mkexy put.rb
  3. #exeファイルの作成
  4. >exerb put.exy

ポイント

・exerbで自分自身のファイル名はExerbRuntime.filepathで取得する必要がある
・exerbでドラッグアンドドロップされたファイル名は普通にARGVに入る

参考サイト

net/ftp - Rubyリファレンスマニュアル
Greenbear Diary - RubyText 0.1 , Exerb化したexeの置かれているパスを取得する
ドラッグアンドドロップしたファイルをeuc-jpに変換するRubyスクリプト - 今日は長閑にtamago_girai
Exerb Project
FTPからのダウンロード - みずぴー日記