2

私は現在、Ruby でシングルトン メソッドとシングルトン クラスを練習/学習していますが、疑問に思いました。与えられた:

myobject = Object.new

これを行うことに違いはありますか:

def myobject.mymethod
end

そしてこれを行う:

class << myobject
 def mymethod
 end
end

ある場合、いつどちらを使用しますか? どのような影響がありますか?

4

1 に答える 1

2

次のように、 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を使用します。

于 2012-04-27T05:52:48.660 に答える