优化和命名空间

时间:2017-11-22 17:43:43

标签: ruby monkeypatching refinements

尝试修补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)

1 个答案:

答案 0 :(得分:2)

  

这是名称空间问题吗?

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

set

最初,只有>>> ypos = [5,3,1] # y and z being same as above >>> ity = iter(e for i, e in sorted(zip(ypos, y))) >>> [next(ity if i+1 in syp else itz) for i in range(len(y)+len(z))] [15, 12, 13, 14, 11] ,这是脚本范围的,即优化是在脚本的整个剩余部分的范围内。 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 后来出现,它将精炼范围限定在词法类定义体中。