咳といいます。

Ruby本、昨日ASCII CEで注文しました。
ruby-listの話題に取り残されていてさびしいです。


pdfのyieldの説明をみながら drb.rb でもイテレータが
扱えるようにいじってみました。
ローカル側のイテレータのブロックをProcにして
DRbObjectで包んでリモート側に与て実現してます。
# 効率悪そう

each や collect みたいなのは動くようになったのですが、
イテレータのブロック中でのbreakやnextなどがうまく対応
できません。いい方法はないかな。


以下 drb.rb に対するパッチです。
http://www2a.biglobe.ne.jp/~seki/ruby/druby-beta.tar.gz にも
置きますです。


Index: drb.rb =================================================================== RCS file: /home/mas/lib/cvsroot/labo/ruby/druby/drb.rb,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** drb.rb 1999/10/26 14:51:07 1.5 --- drb.rb 1999/11/02 15:16:44 1.6 *************** *** 2,8 **** =begin Tiny distributed Ruby --- dRuby 1.0 Copyright (c) 1999 Masatoshi SEKI ! $Id: drb.rb,v 1.5 1999/10/26 14:51:07 mas Exp $ DRb --- dRuby module. DRbUndumped --- Mixin class. DRbProtocol --- Mixin class. --- 2,8 ---- =begin Tiny distributed Ruby --- dRuby 1.0 Copyright (c) 1999 Masatoshi SEKI ! $Id: drb.rb,v 1.6 1999/11/02 15:16:44 mas Exp $ DRb --- dRuby module. DRbUndumped --- Mixin class. DRbProtocol --- Mixin class. *************** *** 62,74 **** return str end ! def send_request(soc, ref,msg_id, *arg) dump(ref, soc) dump(msg_id.id2name, soc) dump(arg.length, soc) arg.each do |e| dump(e, soc) end end def recv_reply(soc) --- 62,75 ---- return str end ! def send_request(soc, ref,msg_id, *arg, &b) dump(ref, soc) dump(msg_id.id2name, soc) dump(arg.length, soc) arg.each do |e| dump(e, soc) end + dump(b, soc) end def recv_reply(soc) *************** *** 85,91 **** argc.times do argv.push Marshal::load(soc) end ! [ro, msg, argv] end def send_reply(soc, succ, result) --- 86,93 ---- argc.times do argv.push Marshal::load(soc) end ! block = Marshal::load(soc) ! [ro, msg, argv, block] end def send_reply(soc, succ, result) *************** *** 109,125 **** @ref = obj.id if obj end ! def method_missing(msg_id, *a) if @uri == DRb.uri if @ref obj = ObjectSpace._id2ref(@ref) else obj = DRb.front end ! return obj.__send__(msg_id, *a) end ! succ, result = DRbConn.new(@uri).send_message(self, msg_id, *a) raise result if ! succ result end --- 111,127 ---- @ref = obj.id if obj end ! def method_missing(msg_id, *a, &b) if @uri == DRb.uri if @ref obj = ObjectSpace._id2ref(@ref) else obj = DRb.front end ! return obj.__send__(msg_id, *a) &b end ! succ, result = DRbConn.new(@uri).send_message(self, msg_id, *a, &b) raise result if ! succ result end *************** *** 132,141 **** @host, @port = parse_uri(remote_uri) end ! def send_message(ref, msg_id, *arg) begin soc = TCPSocket.open(@host, @port) ! send_request(soc, ref, msg_id, *arg) recv_reply(soc) ensure soc.close if soc --- 134,143 ---- @host, @port = parse_uri(remote_uri) end ! def send_message(ref, msg_id, *arg, &block) begin soc = TCPSocket.open(@host, @port) ! send_request(soc, ref, msg_id, *arg, &block) recv_reply(soc) ensure soc.close if soc *************** *** 171,182 **** begin s = ns begin ! ro, msg, argv = recv_request(s) obj = ro_to_obj(ro) ! result = obj.__send__(msg.intern, *argv) succ = true rescue result = $! succ = false end send_reply(s, succ, result) --- 173,194 ---- begin s = ns begin ! ro, msg, argv, block = recv_request(s) obj = ro_to_obj(ro) ! if block ! result = obj.__send__(msg.intern, *argv) do |*x| ! block.call(*x) ! end ! else ! result = obj.__send__(msg.intern, *argv) ! end succ = true rescue result = $! + if $VERBOSE + p $! + $@.each do |x| puts x end + end succ = false end send_reply(s, succ, result)