【问题标题】:Refinements and namespaces细化和命名空间
【发布时间】:2017-11-22 17:43:42
【问题描述】:

尝试修补 net/http 并使其仅适用于一个服务类。改进似乎是要走的路。下面的猴子补丁有效,但改进无效。这是命名空间问题吗?该项目在 ruby​​ 2.3.0 上,但也尝试过 2.4.1,似乎只有猴子补丁被应用。

带有猴子补丁:

module Net
  class HTTPGenericRequest
    def write_header(sock, ver, path)
      puts "monkey patched!"
      # patch stuff...
    end
  end
end

Service.new.make_request
# monkey patched!

经过改进:

module NetHttpPatch
  refine Net::HTTPGenericRequest do
    def write_header(sock, ver, path)
      puts "refined!"
      # patch stuff...
    end
  end
end

class Service
  using NetHttpPatch
end

Service.new.make_request
# :(

更新:

这似乎是类似的范围明智?显然,当 net/http 发出请求时会发生更复杂的事情,那么它会失去作用域吗?

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class Service
  using TimeExtension

  def one_hour
    puts 1.hours
  end
end

puts Service.new.one_hour
# 60

更新更新:

nvm,我知道现在发生了什么 :) 必须让你的大脑不要将 using 与 mixins 的工作原理混为一谈。

module TimeExtension
  refine Fixnum do
    def hours
      self * 60
    end
  end
end

class Foo
  def one_hour
    puts 1.hours
  end
end


class Service
  using TimeExtension

  def one_hour
    puts 1.hours
  end

  def another_hour
    Foo.new.one_hour
  end
end

puts Service.new.one_hour
# 60
puts Service.new.another_hour
# undefined method `hours' for 1:Fixnum (NoMethodError)

【问题讨论】:

    标签: ruby monkeypatching refinements


    【解决方案1】:

    这是命名空间问题吗?

    这是一个范围问题。 Refinements are lexically scoped:

    class Service
      using NetHttpPatch
      # Refinement is in scope here
    end
    
    # different lexical scope, Refinement is not in scope here
    
    class Service
      # another different lexical scope, Refinement is *not* in scope here!
    end
    

    最初,只有main::using,它是脚本范围的,即精炼在脚本的整个其余部分的范围内。 Module#using 稍后出现,它将细化范围限定为词法类定义体。

    【讨论】:

    • 用一个更简单的例子更新了问题,当从新实例调用时确实添加了细化,可能会遗漏一些东西:)
    猜你喜欢
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多