Friday, November 07, 2008

DRuby + Observer Pattern

drubyとobserverパターンを使ったリモートタイマー
クライアント・サーバー間のオブジェクトの転送をユニバーサル変数を介して実現するアイディア
ユニバーサル変数はダブルアンダースコアをプリフィクスした文字列
ユニバーサル変数への代入時にこれをローカル変数と区別する必要がありselfを前置しなければならない点がダサい

drb_server.rb

   1  require "druby"

   2  

   3  class Tick

   4    include Observable

   5    def start

   6      loop do

   7        now = Time.now

   8        notify_observers(now)

   9        print "Current Time: #{now}\n"

  10        sleep 1

  11      end

  12    end

  13  end

  14  tick = Tick.new

  15  self.__hello = tick

  16  tick.start

  17  

  18  

  19  puts 'Press [return] to exit'

  20  gets


drb_client

   1  require "druby"

   2  

   3  class Timer

   4    def update(now)

   5      print "#{now.sec}\n" if now.sec % 10 == 0

   6    end

   7    def _dump(dummy)

   8      raise TypeError, "can't dump"

   9    end

  10  end

  11  

  12  timer = Timer.new

  13  

  14  tick = __hello

  15  tick.add_observer(timer)

  16  

  17  puts 'Press [return] to exit'

  18  gets


druby.rb

   1  require "drb/drb"

   2  module DRuby

   3    include DRbUndumped

   4    URI = 'druby://localhost:12345'

   5  

   6    def self.universal_variable=(obj)

   7      DRb.start_service(URI, obj)

   8    end

   9  

  10    def self.universal_variable

  11      DRb.start_service

  12      DRbObject.new_with_uri(URI)

  13    end

  14  

  15    class << self

  16      alias :uv= :universal_variable=

  17      alias :uv :universal_variable

  18    end

  19  end

  20  

  21  module Observable

  22    def add_observer(observer)

  23      @observers ||= []

  24      @observers << observer

  25    end

  26  

  27    def notify_observers(*objs)

  28      return nil unless defined? @observers

  29      @observers.each do |obs|

  30        obs.update(*objs)

  31      end

  32    end

  33  

  34  end

  35  

  36  class Object

  37    URI = 'druby://localhost:12345'

  38  

  39    def singleton_klass

  40      class << self; self end

  41    end

  42  

  43    def method_missing(name, *args, &block)

  44      if name[0,2] == "__"

  45        if name[-1] == "=" 

  46          DRb.start_service(URI, args[0])

  47        else

  48          DRb.start_service

  49          DRbObject.new_with_uri(URI)

  50        end

  51      else

  52        super

  53      end

  54    end

  55  end


No comments: