2016-05-28 8 views
2

initializeメソッドでインスタンス変数を初期化するときに、@var = var_valueself.send("var=", var_value)の間に違いがありますか?これは私が意味するのは、たとえそれがスタイルの理由を意味するとしても、何らかの理由で一方の方法を他の方法よりも優先させる理由がありますか?@var = var_valとself.send( "var ="、var_val)の間に違いはありますか?

class MySuperClass 
    attr_accessor :columns, :options 
end 

class MySubClass < MySuperClass 
    def initialize(columns, options) 
    @columns = columns 
    @options = options 
    end 
end 

class MyOtherSubClass < MySuperClass 
    def initialize(columns, options) 
    self.send("columns=", columns) 
    self.send("options=", options) 
    end 
end 

答えて

4

違いがあります。

@var = xは、インスタンス変数に割り当てます。メソッド呼び出しはありません。仮想ディスパッチはありません。割り当てを傍受する方法はありません。

sendは、方法(または「メッセージを送信する」)を呼び出します。文脈では、:var=は、がインスタンス変数割り当てをにラップする査定者の「設定メソッド」です。しかし、これはメソッドであり、仮想ディスパッチを継承して呼び出され、サブタイプでオーバーライドされることを含め、何かを行うことができます。

@var = x

に真当量instance_variable_setあろう:

self.instance_variable_set(:@var, x) 

この場合sendを使用することは奇数です。アクセッサを直接使用する(self.columns = columns)。

「より正確」は、確立されたカプセル化のレベルと、そのタイプと用途で定義された契約によって決まります。私は一般的に、サブタイプが関係しているときにアクセサの側でエラーを出します。

+0

この場合、 'instance_variable_set'が奇数であっても、最初のパラメータが動的な場合、つまりプログラムの過程で評価される場合にのみ使用されるので、これは奇妙です。 –

+0

@MladenJablanovićはい、両方とも奇妙です。厳密には操作を区別することでした。 – user2864740