Ruby define_singleton_method 时调用自身原来方法

wwwicbd · 2018年04月13日 · 最后由 UlyssesZhan 回复于 2018年04月13日 · 1648 次阅读
str = "focus"

p str.upcase

str.define_singleton_method(:upcase) do
  "singleton:" + self.send(:upcase)
end

p str.singleton_methods
p str.upcase

# "FOCUS"
# [:upcase]
# q.rb:6:in `block in <main>': stack level too deep (SystemStackError)
#         from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
# from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
# from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
# ... 4355 levels...
#     from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
#         from q.rb:6:in `block in <main>'
# from q.rb:10:in `<main>'

问题 1:

如上,如果想在 define_singleton_method 中使用对象原来的方法 (例子中的 upcase 方法), 要怎么做呢?

问题 2:

如果在祖先链上有许多同名方法,怎么才能调用具体某个类下的那个方法呢? (或者中某个类开始向前查找)

谢谢

str = "focus"

p str.upcase

str.define_singleton_method(:upcase) do
  "singleton:" + super()
end

p str.singleton_methods
p str.upcase

# "FOCUS"
# [:upcase]
# "singleton:FOCUS"

对于问题 1,1 楼已经回答 对于问题 2,其实 Ruby 中类的继承关系是非常简单的,通常情况(也就是没有 super 之类的情况)下,子类相当于把你定义的父类的东西和你定义的子类的东西前后拼接在一起。我们知道两次定义同一个方法,后一次会覆盖前一次,所以子类是无法追溯到父类的父类的同名方法的

需要 登录 后方可回复, 如果你还没有账号请 注册新账号