Путаница с супер - PullRequest
       3

Путаница с супер

0 голосов
/ 15 ноября 2010

Переопределить 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

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

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 метод super вызывается с переменной options, котораяотносится к Fixnum значения 42, а не к объекту, на который изначально ссылался options.

При использовании options.merge! вы измените объект хеша, который был передан вамЭто означает, что объект, на который ссылается переменная original_child_options, теперь изменен, как это видно в строке Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}.

(Примечание: я изменил options на 42 в SecondChild, а незвоните Hash#merge, потому что я хотел показать, что это был не просто случай побочных эффектов на объект)

2 голосов
/ 15 ноября 2010

первый возврат результата супер звонка.Так что, как будто вы никогда не обращаетесь к чему-то в вашем случае.

Второй вызов super перед вашими изменениями и изменения параметров после.

Полагаю, вы действительно хотите:

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