私は現在、Ruby でシングルトン メソッドとシングルトン クラスを練習/学習していますが、疑問に思いました。与えられた:
myobject = Object.new
これを行うことに違いはありますか:
def myobject.mymethod
end
そしてこれを行う:
class << myobject
def mymethod
end
end
ある場合、いつどちらを使用しますか? どのような影響がありますか?
私は現在、Ruby でシングルトン メソッドとシングルトン クラスを練習/学習していますが、疑問に思いました。与えられた:
myobject = Object.new
これを行うことに違いはありますか:
def myobject.mymethod
end
そしてこれを行う:
class << myobject
def mymethod
end
end
ある場合、いつどちらを使用しますか? どのような影響がありますか?
次のように、 ruby --dump insを使用して結果を調べます。
1.
# test.rb
myobject = Object.new
def myobject.mymethod
end
ruby --dump in test.rbを実行します
出力は次のとおりです。
D:\>ruby --dump ins test.rb
== disasm: <RubyVM::InstructionSequence:<main>@test.rb>=================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] myobject
0000 trace 1 ( 1)
0002 getinlinecache 9, <ic:0>
0005 getconstant :Object
0007 setinlinecache <ic:0>
0009 send :new, 0, nil, 0, <ic:1>
0015 setdynamic myobject, 0
0018 trace 1 ( 3)
0020 putspecialobject 1
0022 getdynamic myobject, 0
0025 putobject :mymethod
0027 putiseq mymethod
0029 send :"core#define_singleton_method", 3, nil, 0, <ic:2>
0035 leave
== disasm: <RubyVM::InstructionSequence:mymethod@test.rb>===============
0000 trace 8 ( 3)
0002 putnil
0003 trace 16 ( 4)
0005 leave
2.
# test.rb
myobject = Object.new
class << myobject
def mymethod
end
end
ruby --dump in test.rbを実行します
出力は次のとおりです。
D:\>ruby --dump ins test.rb
== disasm: <RubyVM::InstructionSequence:<main>@test.rb>=================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] myobject
0000 trace 1 ( 1)
0002 getinlinecache 9, <ic:0>
0005 getconstant :Object
0007 setinlinecache <ic:0>
0009 send :new, 0, nil, 0, <ic:1>
0015 setdynamic myobject, 0
0018 trace 1 ( 3)
0020 getdynamic myobject, 0
0023 putnil
0024 defineclass :singletonclass, singletonclass, 1
0028 leave
== disasm: <RubyVM::InstructionSequence:singletonclass@test.rb>=========
0000 trace 2 ( 3)
0002 trace 1 ( 4)
0004 putspecialobject 1
0006 putspecialobject 2
0008 putobject :mymethod
0010 putiseq mymethod
0012 send :"core#define_method", 3, nil, 0, <ic:0>
0018 trace 4 ( 6)
0020 leave ( 4)
== disasm: <RubyVM::InstructionSequence:mymethod@test.rb>===============
0000 trace 8 ( 4)
0002 putnil
0003 trace 16 ( 5)
0005 leave
したがって、 def myobject.method は、最初に core#define_singleton_method メッセージを myobject に送信し、次に core#define_singleton_method メッセージの実装が myobject のシングルトン クラスを取得し、メソッド定義をシングルトン クラスに追加します。
class << myobject 最初に singletonclass メッセージを myobject に送信し、次に core#define_method メッセージを myobject の singletonclass に送信します。
実際には、
obj に対していくつかのシングルトン メソッドを定義する場合は、class << objを使用します。
obj に対してシングルトン メソッドのみを定義する場合は、def obj.methodを使用します。