0

尝试修补 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,我知道现在发生了什么 :) 必须让你的大脑不要混淆usingmixins 的工作方式。

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)
4

1 回答 1

2

这是命名空间问题吗?

这是一个范围问题。细化是词法范围的

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,它是脚本范围的,即 Refinement 在脚本的整个其余部分的范围内。Module#using后来出现了,它将细化范围限定为词法类定义主体。

于 2017-11-22T20:38:49.607 回答