2010-11-15 65 views
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

TL;博士: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超級方法被調用與可變options它指的值42一個Fixnum,而不是與options最初提到的對象。

隨着使用options.merge!,你會修改傳遞給你的哈希對象,這意味着該對象稱爲由可變original_child_options現在修改,如可以在Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]}線可以看出。

(注:我在SecondChild改變options到42,而不是調用Hash#merge,因爲我想證明這不是在物體上的副作用僅僅是一種情況)

+0

謝謝你的好例子。如果我將在OriginChild和SecondChild的選項之前寫入超級,那麼它們會有什麼不同。 – 2010-11-16 13:56:56

+0

@Krunal:你可以修改上面的代碼,然後在irb(Interactive Ruby Shell)中重新運行它。你聽說過irb,對吧? – 2010-11-16 22:30:49

2

第一回超級調用的結果。所以這就像你從來沒有對你的情況。

第二次調用super之前更改並更改選項後。

我想你真的想:

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

你不需要''!在這種情況下。 – 2010-11-15 17:20:12

+1

-1場景1中的第一行將修改變量'options'引用的對象,那麼它將如何成爲「你從不[某事]」? – 2010-11-16 00:07:52