与超级混淆

发布于 2024-10-02 04:28:37 字数 344 浏览 4 评论 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

Override to_xml.

What are the difference between these codes. Can someone explain it with proper example ?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

反目相谮 2024-10-09 04:28:37

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 时,使用变量 options 调用 super 方法,该变量引用 Fixnum< /code> 的值 42,而不是最初由 options 引用的对象。

通过使用 options.merge!,您可以修改传递给您的哈希对象,这意味着变量 original_child_options 引用的对象现在已被修改,如下所示可以在 Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]} 行中看到。

(注意:我在 SecondChild 中将 options 更改为 42,而不是调用 Hash#merge,因为我想表明这不仅仅是对对象产生副作用的情况)

tl;dr: super behaves in unexpected ways, and variables matter, not just objects.

When super is called, it's not called with the object that was passed in.

It's called with the variable that is called options at the time of the call. For example, with the following code:

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

Which produces the output

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: {}

You can see that with SecondChild the super method is called with the variable options which refers to a Fixnum of value 42, not with the object that was originally referred to by options.

With using options.merge!, you'd modify the hash object that was passed to you, which means that the object referred to by the variable original_child_options is now modified, as can be seen in the Original child options after method called: {:methods=>[:murm_case_name, :murm_type_name]} line.

(Note: I changed options to 42 in SecondChild, rather than call Hash#merge, because I wanted to show it wasn't merely a case of side effects on an object)

美胚控场 2024-10-09 04:28:37

第一个返回 super 调用的结果。所以就像你从来没有对你的情况做某事一样。

第二次在更改之前调用 super 并在更改之后调用 super 。

我想你真的想要:

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

the first return the result of super call. So it's like you never to something in your case.

The second call super before your change and change options after.

I suppose you really want :

def to_xml(options = {})
  super(options.merge!(:methods  => [ :murm_case_name, :murm_type_name ]))
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文