< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事
N :次の記事(スレッド移動)
|<:スレッドの先頭
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
In message [ruby-list:8228] Re: Delegation
Yukihiro Matsumoto <matz / netlab.co.jp>
> | 1. このようにした場合,何か問題が起こり得るでしょうか.
>
> method_missingは「メソッドが定義されていない」時にしか呼ばれ
> ませんから,Objectで定義されているメソッドに対しては転送が行
> われません.delegate.rbでやってるのと同様の方法で明示的に転
> 送してやれば良いんでしょうけど.
Object で定義されていて,Delegator で preserved でないメソッドを undef
しているんで,結構大丈夫かな?
> | 2. 初期オブジェクトが不定な delegation を上手く書く,もっと上手いや
> | り方は考えられるでしょうか.
>
> method_missing以上の方法は無いと思いますよ.
「とりあえず書いてみた」ものを回収できたのでちょっとこの後につけてみま
す.
1. 直接実行することができます.
2. 引数で Future の例の方の,メインスレッドの待ち時間を変えることが
できます
あんまり使い道はなさそうですけど.Promise(lazy evaluation)はまだしも
Future はシングルプロセッサだとあんまり面白くないですね.IO バウンドな
スレッドがあると役に立つのかな?
# 改ページは入らんはテキストを挿入すると勝手に空行をカットするは,どう
# も Outlook Express は性に合わない (^^;
# なんか変なものが出ていってたら教えてください.
===========================================================================
柳川和久 @ 東大阪市 . 大阪府
kjana / os.xaxon.ne.jp June 8, 1998
「え,月ってただ空に描いてあるだけじゃなかったの? うそー」
「うそーってエレン....」
# これは delegator.rb からほぼそのまま持ってきたもの
class UDelegator
def initialize(obj)
preserved = ::Kernel.instance_methods
for t in self.type.ancestors
preserved |= t.instance_methods
break if t == UDelegator
end
preserved -= ["__getobj__","to_s","nil?","to_a","hash","dup","==","=~"]
for method in obj.methods
next if preserved.include? method
#eval "def self.#{method}(*args,&block); __getobj__.__send__(:#{method}, *args,&block); end"
undef_method method # これと method_missing だけが違う
end
end
def method_missing(msg, *arg, &block)
__getobj__.__send__(msg, *arg, &block)
end
def __getobj__
raise NotImplementError, "need to define `__getobj__'"
end
end
class Promise <UDelegator
def initialize
@proc = Proc.new
end
def __getobj__
return @obj if @obj
@obj = @proc.call
end
end
def delay(&block)
Promise.new(&block)
end
class Future <UDelegator
def initialize(&block)
@th = Thread.new(&block)
@th.abort_on_exception
end
def __getobj__
return @obj if @obj
@obj = @th.value
end
end
def future(&block)
Future.new(&block)
end
if __FILE__ == $0
class Foo
def initialize(a); @a = a; end
def [](i); @a[i]; end
def []=(i, v); @a[i] = v; end
def isa; type; end
end
puts "promise example"
foo = delay {a = Foo.new([]); for i in 1..100; print "#{i} "; a[i] = i; end; puts; a}
puts "here is `non touched' promise #{foo}"
puts "# preserved method call: promise is not evaluated here."
puts "foo.type = #{foo.type}"
puts "# unpreserved method call: promise is `touched' here."
puts "foo.isa = #{foo.isa}"
puts "foo[10] = #{foo[10]}"
puts
puts "future example"
st = 15
st = ARGV.shift.to_i if ARGV.size > 0
foo = future {sleep 10; a = Foo.new([]); for i in 1..100; print "#{i} "; a[i] = i; end; puts; a}
puts "here is `non touched' future #{foo}"
puts "# preserved method call: future is not evaluated here."
puts "foo.type = #{foo.type}"
puts "some time consuming task take place...."
sleep st;
puts "# unpreserved method call: future is `touched' here."
puts "foo.isa = #{foo.isa}"
puts "foo[10] = #{foo[10]}"
end