咳といいます。

> drbを使って、チャット(メッセージ交換?)プログラムを
> 書いてみたのですが、メソッドが呼ばれたときに、その呼び主を
> 知りたいと思ったのですが、知ることはできますか?

いまのとこできないです。
ローカルから呼ばれたのか、リモートから呼ばれたのかを
意識せずに使えるようにしてみたかったので…。
やっぱり必要でしょうか?


ChatServerのdistribute(str)に、呼び出し側のリファレンスを渡すのが
簡単かなぁ。

逆にChatServer側から client を呼んでみるというのはどうでしょう?

ちょっときれいにかけないのですが、こんな感じ。

-- BEGIN dhats.rb
#!/usr/local/bin/ruby
require 'thread'
require 'drb.rb'

class ChatServer
  def initialize
    @mutex = Mutex.new
    @members = {}
  end

  def client_loop(there)
    Thread.start do
      begin
	while true
	  ev = there.event
	  distribute(there, ev)
	end
      ensure
	remove_member(there)
      end
    end
  end

  def add_member(there)
    th = client_loop(there)
    name = there.name
    @mutex.synchronize do
      @members[there] = [th, name]
    end
  end

   def remove_member(there)
     @mutex.synchronize do
       @members.delete(there)
     end
   end

   def distribute(there, str)
     name = @members[there][1]
     msg = "<#{name}> #{str}"
     msg2 = ">#{name}< #{str}"
     @mutex.synchronize do
       for m in @members.keys
	 if m == there
	   m << msg2
	 else
	   m << msg
	 end
       end
     end
   end
end

if __FILE__ == $0
  here = "druby://#{`hostname`.chomp}:7640"
  puts here
  DRb.start_service(here, ChatServer.new)
  DRb.thread.join
end
-- END

-- BEGIN dhatc.rb
#!/usr/local/bin/ruby

require 'drb.rb'

class ChatClient
  def initialize(name)
    @name = name
  end
  attr :name

  def event
    gets
  end

  def <<(str)
    puts str
  end
end

if __FILE__ == $0
  begin
    there = ARGV.shift
    port = ARGV.shift.to_i
    name = ARGV.shift
    raise "usage" unless (there and port and name)
  rescue
    $stderr.puts("usage: #{$0} <server_uri> <your_port> <your_name>")
    exit 1
  end
  here = "druby://#{`hostname`.chomp}:#{port.to_s}"
  lo = DRbObject.new(ChatClient.new(name), here)
  DRb.start_service(here, lo)
  ro = DRbObject.new(nil, there)
  ro.add_member(lo)
  DRb.thread.join
end
-- END