2010-11-15 66 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