今までの章ではクライアント側からサーバ側に接続する時にも「DRb.start_service」とDRbサーバを立ち上げていましたが、不思議に思われたことはないでしょうか?
DRb.start_service
DRbObject.new_with_uri('druby://:1234')
DRb.start_serviceはなくてもリモートオブジェクトから値をとってくる事はできます。
irb(main):015:0> h = DRbObject.new_with_uri('druby://:1234')
=> #<DRb::DRbObject:0x10031cd00 @ref=nil, @uri="druby://:1234">
irb(main):013:0> h => #<DRb::DRbObject:0x100348c98 @ref=nil, @uri="druby://:1234"> irb(main):014:0> h['a'] => 1
ではわざわざなぜDRb.start_serviceを指定しているか。これは「参照渡し」を考えると理解できます。まずは上のハッシュをmapメソッドでイタレートしてみましょう。
irb(main):018:0> h.map{|a| a}
DRb::DRbConnError: DRb::DRbServerNotFound
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/drb/drb.rb:1658:in `current_server'
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/drb/drb.rb:1726:in
おや。DRb::DRbServerNotFoundというメッセージが出てきましたね。これは実はmapというメソッドが返してくるEnumeratorオブジェクトはMarshal.dump出来ないために参照渡しをします。そのためサーバー側でイタレートしているつもりが実はクライアントサーバ側でイタレートする必要があるのですが、クライアント自身のサーバが立ち上がっていないために先ほどのようなエラーがでてきたのです。
irb(main):019:0> DRb.start_service
irb(main):020:0> h.map{|a| a}
=> [["a", 1]]
クライアントサイドでサーバを立ち上げてからもう一度試して下さい。今度は上手くいきましたね。こういった事態を避けるために、クライアント側がサーバ側に接続するときも常に「DRb.start_service」をしておくのをお勧めします