0

to_xml をオーバーライドします。

これらのコードの違いは何ですか。誰かが適切な例で説明できますか?

1.

def to_xml(options = {})
  options.merge!(:methods  => [ :murm_case_name, :murm_type_name ])
  super
end

2.

def to_xml(options = {})
  super
  options.merge!(:methods  => [ :murm_case_name, :murm_type_name ])
end
4

2 に答える 2

4

tl; dr: super予期しない動作をし、オブジェクトだけでなく変数も重要です。

super呼び出されると、渡されたオブジェクトでは呼び出されません。

optionsこれは、呼び出し時に呼び出される変数を使用して呼び出されます。たとえば、次のコードを使用します。

class Parent
  def to_xml(options)
    puts "#{self.class.inspect} Options: #{options.inspect}"
  end
end

class OriginalChild < Parent
  def to_xml(options)
    options.merge!(:methods  => [ :murm_case_name, :murm_type_name ])
    super
  end
end

class SecondChild < Parent
  def to_xml(options)
    options = 42
    super
  end
end

begin
  parent_options, original_child_options, second_child_options = [{}, {}, {}]
  Parent.new.to_xml(parent_options)
  puts "Parent options after method called: #{parent_options.inspect}"
  puts
  OriginalChild.new.to_xml(original_child_options)
  puts "Original child options after method called: #{original_child_options.inspect}"
  puts
  second_child_options = {}
  SecondChild.new.to_xml(second_child_options)
  puts "Second child options after method called: #{second_child_options.inspect}"
  puts
end

これは出力を生成します

Parent Options: {}
Parent options after method called: {}

OriginalChild Options: {:methods=>[:murm_case_name, :murm_type_name]}
Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}

SecondChild Options: 42
Second child options after method called: {}

スーパーメソッドでは、元々が参照されていたオブジェクトではなく、値のを参照するSecondChild変数で呼び出されていることがわかります。optionsFixnum42options

を使用してoptions.merge!、渡されたハッシュオブジェクトを変更します。これは、行に示されているように、変数によって参照されるオブジェクトがoriginal_child_options変更されることを意味しますOriginal child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}

(注:optionsSecondChildでは、呼び出しではなく42に変更しました。Hash#mergeこれは、オブジェクトに対する単なる副作用の場合ではないことを示したかったためです)

于 2010-11-16T00:00:00.840 に答える
2

最初はスーパーコールの結果を返します。ですから、あなたの場合、何かを決してしないようです。

2 番目の呼び出しは、変更前に super を呼び出し、変更後にオプションを変更します。

私はあなたが本当に欲しいと思います:

def to_xml(options = {})
  super(options.merge!(:methods  => [ :murm_case_name, :murm_type_name ]))
end
于 2010-11-15T16:57:20.753 に答える